gcc 内联汇编

gcc 内联汇编,第1张

如下,不懂VC下汇编的规则,不知道那个RADIX是怎么和函数名联系起来的,我就直接用数字3了。加了一些注释方便你读,另外,在具体运算的汇编前后,我加了连续的三个nop空指令方便你反汇编或者debug的时候看到底哪些是通过内联汇编生成的指令,哪些是编译器自己产生的。你可以自行去掉。

unsigned int Div_3(unsigned long long x, unsigned long long pRemainder)

{

register void x_addr asm ("ecx") = &x;

asm volatile("nop;nop;nop");

asm volatile ("movl (%%ecx), %%eax\n\t" / copy low 32bit of x to eax /

"movl 4(%%ecx), %%edx\n\t" / copy high 32bit to edx /

"movl $3, %%ebx\n\t" / radix = 3 /

"div %%ebx\n\t"

"movl $0, 4(%1)\n\t" / high 32bit of remainder is 0 /

"movl %%edx, (%1)\n\t" / remainder /

: / no output operands /

: "r" (x_addr), "r" (pRemainder)

: "eax", "ebx", "edx");

asm volatile("nop;nop;nop");

}

在 Visual C++ 中使用内联汇编- -使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。这里,我们就以 Visual Studio NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。 内联汇编代码可以使用 C/C++ 变量和函数,因此它能非常容易地整合到 C/C++ 代码中。它能做一些对于单独使用 C/C++ 来说非常笨重或不可能完成的任务。一、 优点 使用内联汇编可以在 C/C++ 代码中嵌入汇编语言指令,而且不需要额外的汇编和连接步骤。在 Visual C++ 中,内联汇编是内置的编译器,因此不需要配置诸如 MASM 一类的独立汇编工具。这里,我们就以 Visual Studio NET 2003 为背景,介绍在 Visual C++ 中使用内联汇的相关知识(如果是早期的版本,可能会有些许出入)。 内联汇编代码可以使用 C/C++ 变

没有出错,确实都能运行,是gcc的编译处理太智能了,理由如下:

①gcc的内联汇编的约束是个很智能的有限约束,能从约束里知道你想怎么写:如代码中的“:"=a"(rrr),:"a"(ccc)”就已经告诉了编译器,要让这段内联汇编代码的效果是“rrr=ccc;”,但是要根据上面的汇编代码写。

②因此,以上asm语句中的内联汇编代码,基本可以随便写。如:

⑴最简单的什么都不写(调试前把汇编代码全部注释掉)如图1

图1 已指定约束,没有指定汇编指令时

⑵只写一半,让编译器猜,如图2(或者写无关指令,如图3)

图2 写一半

图3 只给ebx赋了个立即数1

这样,我们知道,这个内联汇编的约束的作用,只是让用户有限定制c语言代码编译中需要使用的汇编代码。

③其实输出不仅可以是ccc,即9,还可以是ccc+1,即10

如图4代码asm volatile("mov %0,%ebx\n\t":"=a"(rrr):"a"(ccc+1));

输出结果是10

③把a约束改成b约束,让ebx寄存器影响结果,不影响结果

所以说,如果需要ebx干预结果,只能把约束拿掉。至于,都可以运行,那完全是gcc编译器的功劳

先看官方示例代码运行成功吗,排除环境问题:

__asm {  

   mov al, 2  

   mov dx, 0xD007  

   out dx, al  

}

>

使用内联汇编写 ,它的格式有两种,一种是__asm 直接接汇编指令语句,

比如,__asm xor eax, eax //清零eax

另一种是加上花括号,类似于一个函数,比如

__asm {

mov eax, 1 ;1到eax

mov ebx, 2 ;2到ebx

add eax, ebx ;eax 和ebx相加

}

使用内联汇编有个好处可以直接使用C/C++中的变量 ,比如

int a = 2;

__asm mov a, 2 //可以使用变量,只有一条

另外使用内联汇编最需要注意的是数组。比如 int a[2] = {1,2} ;

不可以直接

__asm{

mov a[0], 1

mov a[1], 2

}

这样是错误的, 需要 mov a[0], 1 mov a[4],2 为什么是4呢?因为内联汇编转换后是数组a的地址偏移,而不是序号。

vc中的内联汇编 简单的很, 要是在linux中使用内联汇编,费了劲了。。没事欢迎到 百度 0x30 贴吧 分享一下C/C++的心得,或者加入百度知道 0x30 团队,帮助别人的时候,自己 也可以学到东西 。。

#include <stdioh>

int main()

{

  char szStr[128];

  gets(szStr);

  __asm {

    jmp entry

  isletter1:

    cmp al, 'a'

    jl nex

    cmp al, 'z'

    jg nex

    mov ecx, 1

    ret

  isletter2:

    cmp al, 'A'

    jl nex

    cmp al, 'Z'

    jg nex

    mov ecx, 1

    ret

  nex:

    mov ecx, 0

    ret

  entry:

    lea edx, szStr

  loopStart:

    mov al, byte ptr ds:[edx]

    test al, al

    jz ed

    call isletter1

    test ecx, ecx

    jz test2

    sub byte ptr ds:[edx], 'a'-'A'

    jmp nextChar

  test2:

    call isletter2

    test ecx, ecx

    jz nextChar

    add byte ptr ds:[edx], 'a'-'A'

  nextChar:

    inc edx

    jmp loopStart

  ed:

  }

  puts(szStr);

  return 0;

}

以上就是关于gcc 内联汇编全部的内容,包括:gcc 内联汇编、ccs6.0中怎样使用汇编编程、刚接触内联汇编,下面哪里出错了。。。为什么都可以运行。。。可以详细的跟我讲一下吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9275589.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-26
下一篇2023-04-26

发表评论

登录后才能评论

评论列表(0条)

    保存