二章ATT汇编语言讲解材料

上传人:yuzo****123 文档编号:139241485 上传时间:2020-07-20 格式:PPT 页数:36 大小:224KB
返回 下载 相关 举报
二章ATT汇编语言讲解材料_第1页
第1页 / 共36页
二章ATT汇编语言讲解材料_第2页
第2页 / 共36页
二章ATT汇编语言讲解材料_第3页
第3页 / 共36页
二章ATT汇编语言讲解材料_第4页
第4页 / 共36页
二章ATT汇编语言讲解材料_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《二章ATT汇编语言讲解材料》由会员分享,可在线阅读,更多相关《二章ATT汇编语言讲解材料(36页珍藏版)》请在金锄头文库上搜索。

1、第二章 AT 在“asm”后面有时也会加上“_volatile_”表示编译器不要优化代码,后面的指令保留原样 _asm_ _volatile_(hlt);,基本行内汇编,如果有很多行汇编,则每一行后要加上“nt” : asm( pushl %eaxnt movl $0,%eaxnt popl %eax); 或者我们也可以分成几行来写,如: asm(movl %eax,%ebx); asm(xorl %ebx,%edx); asm(movl $0,_booga);,扩展的行内汇编,在扩展的行内汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入寄存器,以及如何

2、将计算结果写回C变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可, GCC会自动插入代码完成必要的操作。,扩展的行内汇编,使用内嵌汇编,要先编写汇编指令模板,然后将C语言表达式与指令的操作数相关联,并告诉GCC对这些操作有哪些限制条件。例如下面的汇编语句: _asm_ _violate_ (movl %1,%0 : =r (result) : r (input); “movl %1,%0”是指令模板;“%0”和“%1”代表指令的操作数,称为占位符,“=r”代表它之后是输入变量且需用到寄存器,指令模板后面用小括号括起来的是C语言表达式 ,其中input是输入变量,该指令会完成

3、把input的值复制到result中的操作,扩展的行内汇编,若把刚才的内嵌汇编语句改成如下: _asm_ _volatile_ (movl %1,%0 : =m (result) : m (input); 只是把“=r”改成了“=m”,“r”改成了“m”,然而在编译这条改过的语句的时候编译器便会报错,因为“r”代表复制的时候借助了寄存器,而“m”则代表直接从内存复制到内存,这样的操作显然是非法的,扩展的行内汇编的语法,内嵌汇编语法如下: _asm_( 汇编语句模板: 输出部分: 输入部分: 破坏描述部分); 即格式为asm ( statements : output_regs : input_

4、regs : clobbered_regs),扩展的行内汇编的语法,扩展行内汇编共分四个部分:汇编语句模板,输出部分,输入部分,破坏描述部分,各部分使用“:”格开,汇编语句模板必不可少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空。,int main(void) int dest; int value=1; asm( movl %1, %0 : =a(dest) : c (value) : %ebx); printf(%dn, dest); return 0; ,扩展的行内汇编的语法,汇编语句模板 汇编语句模板由汇编语句序列组成,语句之间使用“;”

5、、“n”或“nt”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1,%9。指令中使用占位符表示的操作数,总被视为long型(4,个字节),但对其施加的操作根据指令可以是字或者字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在%和序号之间插入一个字母,“b”代表低字节,“h”代表高字节,例如:%h1。,扩展的行内汇编的语法,输出部分 输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C语言变量组成。每个输出操作数的限定字符串必须包含“=”表示它是一个输

6、出操作数。例如:_asm_ _volatile_ (pushfl ; popl %0 ; cli:=g (x) ) 在这里“x”便是最终存放输出结果的C程序变量,而“=g”则是限定字符串,限定字符串表示了对它之后的变量的限制条件,扩展的行内汇编的语法,输入部分 输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符同样也由限定字符串和C语言表达式或者C语言变量组成。例: _asm_ _volatile_ (lidt %0 : : m (real_mode_idt);,扩展的行内汇编的语法,限定字符 限定字符便是内嵌汇编中放在引用的C变量之前的字符,它们的作用是指示编译器如

7、何处理其后的C语言变量与指令操作数之间的关系,例如是将变量放在寄存器中还是放在内存中等,常用的如下:,内嵌汇编示例,例1 int main(void) int result = 2; int input = 1; _asm_ _volatile_ (addl %1, %0: =r(result): r(input); printf(%dn, result); return 0; 这段内嵌汇编原本的目的是输出1+2=3的结果,也就是将input变量的值与result变量的值相加之后再存入result中。可以看到在汇编语句模板中的%1与%0分别代表input与result变量,而“=r”与“r”则

8、表示两个变量在汇编中应该对应两个寄存器,“=”表示result是输出变量。然而实际运行后发现结果实际上是2。这是为什么呢?,内嵌汇编示例,我们用(objdump -j .text S 可执行文件名)这样的命令来查看编译生成后的代码发现这段内嵌汇编经GCC翻译后所对应的AT int input = 1; _asm_ _volatile_ (addl %2,%0:=r(result):r(result),m(input); printf(%dn, result); return 0; 这段内嵌汇编所对应的AT int input = 1; _asm_ _volatile_ (addl %2,%0:

9、=r(result):0(result),m(input); printf(%dn, result); return 0; 在上面的程序中我们使用了占位符“0”表示%0与%1是使用的同一个寄存器,这样就确保了程序的正确性。,内嵌汇编示例,例2 int main(void) int count=3; int value=1; int buf10; asm( cld nt rep nt stosl : : c (count), a (value) , D (buf) ); printf(%d %d %dn, buf0,buf1,buf2); ,经GCC翻译后所对应的AT input = 1; _a

10、sm_ _volatile_ (movl $0, %eax;nt movl %eax, %1;nt movl %2, %eax;nt movl %eax, %0;nt : =m (output), =m(temp) : r (input) :eax); printf(%d %dn, temp,output); return 0; ,内嵌汇编示例,这段内嵌汇编经由GCC转化成的汇编代码如下: movl $0 x1,0 xfffffffc(%ebp) mov 0 xfffffffc(%ebp),%edx mov $0 x0,%eax mov %eax,0 xfffffff4(%ebp) mov %edx,%eax mov %eax,0 xfffffff8(%ebp) 可以看到,由于input、output、temp都是程序局部整型数变量,于是它们实际上是存放在堆栈中的,也就是内存中的某个部分。其中output和temp是输出变量,而且“=m”表明它们应该在内存中,input是输入变量,“r”表明它应存放在寄存器中,于是首先把1存入input变量,然后将变量的值复制给了edx寄存器,在这里我们可以看到内嵌汇编中使用了破环描述符“eax”,这是告诉编译器在程序中eax寄存器已被使用,这样编译器为了避免冲突会将输入变量存放在除eax以外别的寄存器中,如像我们最后看到的edx寄存器。,

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 教学课件 > 高中课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号