写在前面:又是一个新的系列,学习的过程就是成长的过程,重要的是坚持,当然跟之前一样,也是一边学习一边整理总结。用一段在某篇文章看到话来开始这个系列吧:那些跑得更远的人,都是因为别人放弃时,他们还在跑。 所以就这么一直勇敢地跑下去吧。 毕竟,你是一个,连放弃,也做不到的人啊。QQ:993650814
第一篇主要介绍几个常用的汇编语法,后面会用一个嵌入式汇编例子来讲解通常汇编在C中内嵌的用法。
正文:
1、寄存器的引用
引用寄存器要在寄存器前加%,如 mov %eax , %ebx //把寄存器eax中的内容放到ebx寄存器中去
2、操作数顺序: 从源(左)到目的(右),例如上述,eax是源,ebx是目的。
3、常数/立即数的格式
立即数要在前面加$,如mov $4,%ebx
符号常数直接引用,如 mov value, %ebx
引用符号地址要在符号前加$,如 mov $value, %ebx
4、操作数的长度
操作数的长度用加在指令后的符号表示,
b(byte,1个字节) w(word,2个字节) l(long,4个字节),如 mov w %ax, %bx //把ax寄存器的内容复制到bx寄存器中去,长度2Byte
5、嵌入式汇编语句: _asm_("asm statements":outputs:inputs:registers-modified);
asm statements: 加载的代码 汇编语句,可以有多条,会变语句后面用\n\t结束
outputs:inputs:registers-modified :这三者都是可选项。
outputs:输出寄存器
inputs:输入寄存器,
registers-modified:被修改的寄存器
"a"、"b"、"c"、"d"分别表示eax、ebx、ecx、edx
"S"和"D",代表esi、edi
"r":任何寄存器
"0":与上一个寄存器使用同一个寄存器
6、example:
代码中对例子中的汇编每行语句都会进行详细分析:
int main(void)
{
int a1 = 10,b1 = 0;
_asm_("movl %1, %%eax;\\n\r"
"movl %%eax,%%ecx;"
:"=a"(b1)
:"b"(a1)
:"%eax");
printf("a1 = %d,b1 = %d\n",a1,b1);
/*
这段汇编代码中,先看参数部分:
1、输出部分:"=a"(b1) 输出的eax寄存器的内容给了b1;
2、输入部分:"b"(a1) 把输入的a1放到了ebx寄存器中; 即 ebx = a1 =10;
3、会改变的部分:"%eax" eax寄存器会被改变
再来看代码部分
1、"movl %1, %%eax;\\n\r" 在这段代码中, %0代表 "=a"(b1),%1代表 "b"(a1),%2代表 "%eax",
其他代码部分以此类推。
所以这段代码的意思:将ebx的内容给了eax即eax的内容成了10;
2、"movl %%eax,%%ecx;" :这段代码的意思:将eax寄存器的内容放到了ecx中。
整体分析:
输出的寄存器eax的内容是10;
所以打印结果为:a1 = 10,b1 = 10
*/
return 0;
}
另外,还有一处细节需要补充一下,代码中寄存器前面都有两个%%例如"movl %%eax,%%ecx;",为什么是两个%呢?
gcc编译器在编译的时候会自动拿掉一个%,而寄存器引用的时候需要%,所以这里寄存器前面都是两个%。