
如下,不懂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中怎样使用汇编编程、刚接触内联汇编,下面哪里出错了。。。为什么都可以运行。。。可以详细的跟我讲一下吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)