番茄花园-第二章ATT汇编语言.ppt

上传人:豆**** 文档编号:60169230 上传时间:2022-11-14 格式:PPT 页数:36 大小:196KB
返回 下载 相关 举报
番茄花园-第二章ATT汇编语言.ppt_第1页
第1页 / 共36页
番茄花园-第二章ATT汇编语言.ppt_第2页
第2页 / 共36页
点击查看更多>>
资源描述

《番茄花园-第二章ATT汇编语言.ppt》由会员分享,可在线阅读,更多相关《番茄花园-第二章ATT汇编语言.ppt(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、番茄花园-第二章ATT汇编语言 Still waters run deep.流静水深流静水深,人静心深人静心深 Where there is life,there is hope。有生命必有希望。有生命必有希望提纲提纲n nAT&T汇编语言n nGCC内嵌汇编AT&T汇编语言汇编语言n n在Linux中,以.S(或.s)为扩展名的文件是包含汇编语言代码的文件。n n在Linux下有两种方式对AT&T汇编进行编译链接,一种是使用汇编程序GAS和连接程序LD,一种是使用GCC AT&T汇编的编译方式汇编的编译方式n n使用汇编程序使用汇编程序GASGAS和连接程序和连接程序LD LD 第一步:第一

2、步:as sourcecode.s-o objfile.o as sourcecode.s-o objfile.o 将汇编源文件编译成目标文件将汇编源文件编译成目标文件 第二步:第二步:ld objfile.o-o execode ld objfile.o-o execode 将目标文件链接成可执行文件将目标文件链接成可执行文件n n使用使用GCC GCC gcc-o execode sourcecode.S gcc-o execode sourcecode.S 使用使用GCCGCC编译一步就可以编译成可执行文件编译一步就可以编译成可执行文件AT&T汇编示例汇编示例.data.dataoutp

3、ut:.ascii hello worldnoutput:.ascii hello worldn.text.text.globl _start.globl _start_start:_start:movl$4,%eax movl$4,%eax movl$1,%ebx movl$1,%ebx movl$output,%ecx movl$output,%ecx movl$12,%edx movl$12,%edx int$0 x80 int$0 x80 movl$1,%eax movl$1,%eax int$0 x80 int$0 x80 这段程序在linux上编译执行后会输出“hello worl

4、d”。可以看到AT&T与Intel汇编在格式上有着显著的不同 AT&T中的节中的节(Section)在在AT&TAT&T的语法中,一个节由的语法中,一个节由.section.section关键词来关键词来标识,当你编写汇编语言程序时,至少需要有以标识,当你编写汇编语言程序时,至少需要有以下三种节:下三种节:n n.data.data节节 这种节包含程序已初始化的数据,也就是说,包这种节包含程序已初始化的数据,也就是说,包含具有初值的那些变量含具有初值的那些变量 n n.text.text节节 这个节包含程序的代码。需要指出的是,该节是这个节包含程序的代码。需要指出的是,该节是只读节只读节 AT

5、&T中的节中的节(Section)n n.bss.bss节节 这个节包含程序还未初始化的数据,也就是说,这个节包含程序还未初始化的数据,也就是说,包含没有初值的那些变量。当操作系统装入这个包含没有初值的那些变量。当操作系统装入这个程序时将把这些变量都置为程序时将把这些变量都置为0 0 使用使用.bss.bss比使用比使用.data.data的优势在于,的优势在于,.bss.bss节在编译节在编译后不占用磁盘的空间,这样编译、连接生成的代后不占用磁盘的空间,这样编译、连接生成的代码的尺寸会比较小。码的尺寸会比较小。尽管在磁盘上不占空间,但是在可执行文件被读尽管在磁盘上不占空间,但是在可执行文件被

6、读入内存后系统还是会为入内存后系统还是会为.bss.bss节分配内存节分配内存拥有三个节的拥有三个节的AT&T汇编程序示例汇编程序示例.data.dataoutput:.ascii hello worldnoutput:.ascii hello worldn.text.text.globl _start.globl _start_start:_start:movl$4,%eax movl$4,%eax movl$1,%ebx movl$1,%ebx movl$output,%ecx movl$output,%ecx movl$12,%edx movl$12,%edx int$0 x80 int

7、$0 x80 movl$3,%eax movl$3,%eax movl$1,%ebx movl$1,%ebx movl$sentence,%ecx movl$30,%edx int$0 x80 movl$4,%eax movl$30,%edx int$0 x80 movl$1,%eax int$0 x80.bss sentence:.fill 30 程序的功能是首先打印“hello world”,然后让用户输入字符然后将输入的字符打印出来AT&T汇编语言常见指令汇编语言常见指令n n.ascii.ascii 语法:语法:.ascii.ascii“string”.“string”.ascii a

8、scii 表示零个或多个表示零个或多个(用逗号隔开用逗号隔开)字符串,并把字符串,并把每个字符串每个字符串(结尾不自动加结尾不自动加“0”“0”字符字符)中的字符中的字符放在连续的地址单元。于此类似的放在连续的地址单元。于此类似的.asciz.asciz指令定指令定义的字符串会在结尾处自动加义的字符串会在结尾处自动加“0”“0”字符字符n n.fill.fill 语法:语法:.fill repeat,size,value.fill repeat,size,value 含义是反复拷贝含义是反复拷贝sizesize个字节,重复个字节,重复repeatrepeat次次 ,其中,其中sizesize和

9、和valuevalue是可选的,默认值分别为是可选的,默认值分别为1 1和和0 0AT&T汇编语言常见指令汇编语言常见指令n n.globl.globl 语法:语法:.globl symbol.globl symbol .globl .globl使得连接程序使得连接程序(ld)(ld)能够看到能够看到symbolsymbol。如果你。如果你的局部程序中定义了的局部程序中定义了symbolsymbol,那么,与这个局部,那么,与这个局部程序连接的其他局部程序也能存取程序连接的其他局部程序也能存取symbolsymboln n.rept endr.rept endr 语法:语法:.rept cou

10、nt.rept count .endr .endr 把把.rept.rept指令与指令与.endr.endr指令之间的行重复指令之间的行重复countcount次次 AT&T汇编语言常见指令汇编语言常见指令n n.space.space 语法:语法:.space size,fill.space size,fill 这个指令保留这个指令保留sizesize个字节的空间,每个字节的值为个字节的空间,每个字节的值为fill fill n n.byte/.word/.long.byte/.word/.long 语法:语法:.byte/.word/.long expressions.byte/.word

11、/.long expressions 预留预留1 1个字节个字节/字字/双字,并将这个字节的内容赋值为双字,并将这个字节的内容赋值为expressionexpression,若是用逗号隔开的多个,若是用逗号隔开的多个expressionexpression,则为预留多,则为预留多个这样的字节个这样的字节/字字/双字,并将它们的内容依次赋值。双字,并将它们的内容依次赋值。n n.set.set 设定常数,就好像设定常数,就好像C C程序中的程序中的#define#define的作用一样的作用一样 AT&T 与与Intel的汇编语言语法区别的汇编语言语法区别 AT&TAT&T和和IntelInte

12、l汇编语言的语法区别主要体现在操作数前缀、汇编语言的语法区别主要体现在操作数前缀、赋值方向、间接寻址语法、操作码的后缀上赋值方向、间接寻址语法、操作码的后缀上 n n操作数前缀操作数前缀 IntelIntel语法语法 AT&TAT&T语法语法 Mov eax,8 Mov eax,8 movl$8,%eax movl$8,%eax Mov ebx,0ffffh Mov ebx,0ffffh movl$0 xffff,%ebx movl$0 xffff,%ebx int 80h int 80h int$0 x80 int$0 x80 从表中可以看到在AT%T汇编中诸如%eax、%ebx之类的寄存器

13、名字前都要加上%;$8、$0 xffff这样的立即数之前都要加上$。AT&T 与与Intel的汇编语言语法区别的汇编语言语法区别 n n源源/目的操作数顺序目的操作数顺序 IntelIntel语法语法 AT&TAT&T语法语法 MOV EAX,8 MOV EAX,8 movl$8,%eax movl$8,%eax 在Intel语法中,第一个操作数是目的操作数,第二个操作数源操作数。而在AT&T中,第一个数是源操作数,第二个数是目的操作数。AT&T 与与Intel的汇编语言语法区别的汇编语言语法区别 n n寻址方式寻址方式 Intel Intel的指令格式是的指令格式是segregsegreg:

14、base+index*scale+dispbase+index*scale+disp,而而AT&TAT&T的格式是的格式是%segreg%segreg:disp(base,index,scale)disp(base,index,scale)。IntelIntel语法语法AT&TAT&T语法语法eax eax(%eax)(%eax)eax+_variable eax+_variable _variable(%eax)_variable(%eax)eax*4+_array eax*4+_array _array(,%eax,4)_array(,%eax,4)ebx+eax*8+_ebx+eax*8

15、+_array array _array(%ebx,%eax,8)_array(%ebx,%eax,8)在AT&T中,当立即数用在scale/disp中时,不应当在其前冠以“$”前缀,而且scale,disp不需要加前缀“&”。另外在Intel中基地址使用“”、“”,而在AT&T中则使用“(”、“)”。AT&T 与与Intel的汇编语言语法区别的汇编语言语法区别 n n标识长度的操作码前缀标识长度的操作码前缀 在在AT&TAT&T汇编中远程跳转指令和子过程调用指令的操作码汇编中远程跳转指令和子过程调用指令的操作码使用前缀使用前缀“l”“l”,分别为,分别为ljmpljmp,lcalllcall

16、,与之相应的返回指令,与之相应的返回指令伪伪lretlret。例如:。例如:IntelIntel语法语法AT&TAT&T语法语法CALL SECTION:OFFSET CALL SECTION:OFFSET lcall$secion:$offset lcall$secion:$offset JMP FAR SECTION:OFFSET JMP FAR SECTION:OFFSET ljmp$secion:$offset ljmp$secion:$offset RET FAR STACK_ADJUST RET FAR STACK_ADJUST lret$stack_adjust lret$sta

17、ck_adjust AT&T 与与Intel的汇编语言语法区别的汇编语言语法区别 n n标识长度的操作码后缀标识长度的操作码后缀 在在AT&TAT&T的操作码后面有时还会有一个后缀,其含义就是的操作码后面有时还会有一个后缀,其含义就是指出操作码的大小。指出操作码的大小。“l”“l”表示长整数(表示长整数(3232位),位),“w”“w”表示字(表示字(1616位),位),“b”“b”表示字节(表示字节(8 8位)。而在位)。而在IntelIntel的语的语法中,则要在内存单元操作数的前面加上法中,则要在内存单元操作数的前面加上byte ptrbyte ptr、word word ptr,ptr

18、,和和dword ptrdword ptr,“dword”“dword”对应对应“long”“long”。IntelIntel语法语法AT&TAT&T语法语法Mov al,bl Mov al,bl movb%bl,%almovb%bl,%alMov ax,bxMov ax,bxmovw%bx,%axmovw%bx,%axMov eax,ebxMov eax,ebxmovl%ebx,%eaxmovl%ebx,%eaxMov eax,dword ptr Mov eax,dword ptr ebxebxmovl (%ebx),%eaxmovl (%ebx),%eaxGCC内嵌汇编内嵌汇编 n nLi

19、nux操作系统内核代码绝大部分使用C语言编写,只有一小部分使用汇编语言编写,例如与特定体系结构相关的代码和对性能影响很大的代码。GCC提供了内嵌汇编的功能,可以在C代码中直接内嵌汇编语言语句,大大方便了程序设计。基本行内汇编基本行内汇编 n n基本行内汇编很容易理解,一般是按照下面的格基本行内汇编很容易理解,一般是按照下面的格式:式:asm(“statements”);asm(“statements”);n n在在“asm”“asm”后面有时也会加上后面有时也会加上“_volatile_”“_volatile_”表表示编译器不要优化代码,后面的指令保留原样示编译器不要优化代码,后面的指令保留原

20、样 _asm_ _volatile_(hlt);_asm_ _volatile_(hlt);基本行内汇编基本行内汇编 n n如果有很多行汇编,则每一行后要加上如果有很多行汇编,则每一行后要加上“nt”“nt”:asm(pushl%eaxntasm(pushl%eaxnt movl$0,%eaxnt movl$0,%eaxnt popl%eax);popl%eax);n n或者我们也可以分成几行来写,如:或者我们也可以分成几行来写,如:asm(movl%eax,%ebx);asm(movl%eax,%ebx);asm(xorl%ebx,%edx);asm(xorl%ebx,%edx);asm(m

21、ovl$0,_booga);asm(movl$0,_booga);扩展的行内汇编扩展的行内汇编 n n在扩展的行内汇编中,可以将C语言表达式指定为汇编指令的操作数,而且不用去管如何将C语言表达式的值读入寄存器,以及如何将计算结果写回C变量,你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可,GCC会自动插入代码完成必要的操作。扩展的行内汇编扩展的行内汇编n n使用内嵌汇编,要先编写汇编指令模板,然后将使用内嵌汇编,要先编写汇编指令模板,然后将C C语言表达式与指令的操作数相关联,并告诉语言表达式与指令的操作数相关联,并告诉GCCGCC对这些操作有哪些限制条件。例如下面的汇编语对这些

22、操作有哪些限制条件。例如下面的汇编语句:句:_asm_ _violate_ (movl%1,%0:=r(result):_asm_ _violate_ (movl%1,%0:=r(result):r(input);r(input);n n“movl%1,%0”“movl%1,%0”是指令模板;是指令模板;“%0”“%0”和和“%1”“%1”代代表指令的操作数,称为占位符,表指令的操作数,称为占位符,“=r”“=r”代表它之代表它之后是输入变量且需用到寄存器,指令模板后面用后是输入变量且需用到寄存器,指令模板后面用小括号括起来的是小括号括起来的是C C语言表达式语言表达式 ,其中,其中input

23、input是输是输入变量,该指令会完成把入变量,该指令会完成把inputinput的值复制到的值复制到resultresult中中的操作的操作扩展的行内汇编扩展的行内汇编n n若把刚才的内嵌汇编语句改成如下:若把刚才的内嵌汇编语句改成如下:_asm_ _volatile_ (movl%1,%0:=m(result):_asm_ _volatile_ (movl%1,%0:=m(result):m(input);m(input);n n只是把只是把“=r”“=r”改成了改成了“=m”“=m”,“r”“r”改成了改成了“m”“m”,然而在编译这条改过的语句的时候编译器便会,然而在编译这条改过的语句

24、的时候编译器便会报错,因为报错,因为“r”“r”代表复制的时候借助了寄存器,代表复制的时候借助了寄存器,而而“m”“m”则代表直接从内存复制到内存,这样的操则代表直接从内存复制到内存,这样的操作显然是非法的作显然是非法的扩展的行内汇编的语法扩展的行内汇编的语法 n n内嵌汇编语法如下:内嵌汇编语法如下:_asm_(_asm_(汇编语句模板汇编语句模板:输出部分输出部分:输入部分输入部分:破坏描述部分破坏描述部分););n n即格式为即格式为asm(statements:output_regs:input_regs asm(statements:output_regs:input_regs:cl

25、obbered_regs):clobbered_regs)扩展的行内汇编的语法扩展的行内汇编的语法n n扩展行内汇编共分四个部扩展行内汇编共分四个部分:汇编语句模板,输出分:汇编语句模板,输出部分,输入部分,破坏描部分,输入部分,破坏描述部分,各部分使用述部分,各部分使用“:”“:”格开,汇编语句模格开,汇编语句模板必不可少,其他三部分板必不可少,其他三部分可选,如果使用了后面的可选,如果使用了后面的部分,而前面部分为空,部分,而前面部分为空,也需要用也需要用“:”“:”格开,相格开,相应部分内容为空。应部分内容为空。int main(void)int dest;int value=1;asm

26、(movl%1,%0 :=a(dest):c(value):%ebx);printf(%dn,dest);return 0;扩展的行内汇编的语法扩展的行内汇编的语法n n汇编语句模板汇编语句模板 汇编语句模板由汇编语句序列组成,语句之间使用汇编语句模板由汇编语句序列组成,语句之间使用“;”“;”、“n”“n”或或“nt”“nt”分开。指令中的操作数可以使用占位符分开。指令中的操作数可以使用占位符引用引用C C语言变量,操作数占位符最多语言变量,操作数占位符最多1010个,名称如下:个,名称如下:%0%0,%1%1,%9%9。指令中使用占位符表示的操作数,总被视为。指令中使用占位符表示的操作数,

27、总被视为longlong型(型(4 4,个字节),但对其施加的操作根据指令可以是,个字节),但对其施加的操作根据指令可以是字或者字节,当把操作数当作字或者字节使用时,默认为字或者字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式的指明是低字节还低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在是次字节。方法是在%和序号之间插入一个字母,和序号之间插入一个字母,“b”“b”代代表低字节,表低字节,“h”“h”代表高字节,例如:代表高字节,例如:%h1%h1。扩展的行内汇编的语法扩展的行内汇编的语法n n输出部分输出部分 输出部分描述输出操作数,不同的

28、操作数描述符输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符之间用逗号格开,每个操作数描述符由限定字符串和串和C C语言变量组成。每个输出操作数的限定字符语言变量组成。每个输出操作数的限定字符串必须包含串必须包含“=”“=”表示它是一个输出操作数。例如:表示它是一个输出操作数。例如:_asm_asm_ _volatile_(pushfl;popl%0;cli:=g(x)_volatile_(pushfl;popl%0;cli:=g(x)在这里在这里“x”“x”便是最终存放输出结果的便是最终存放输出结果的C C程序变量,程序变量,而而“=g”“=g”则是限定字

29、符串,限定字符串表示了对则是限定字符串,限定字符串表示了对它之后的变量的限制条件它之后的变量的限制条件 扩展的行内汇编的语法扩展的行内汇编的语法n n输入部分 输入部分描述输入操作数,不同的操作数描述符之间使用逗号格开,每个操作数描述符同样也由限定字符串和C语言表达式或者C语言变量组成。例:_asm_ _volatile_(lidt%0:m _asm_ _volatile_(lidt%0:m(real_mode_idt);(real_mode_idt);扩展的行内汇编的语法扩展的行内汇编的语法n n限定字符限定字符 限定字符便是内嵌汇编中放在引用的限定字符便是内嵌汇编中放在引用的C C变量之前

30、的字符,变量之前的字符,它们的作用是指示编译器如何处理其后的它们的作用是指示编译器如何处理其后的C C语言变量与指语言变量与指令操作数之间的关系,例如是将变量放在寄存器中还是放令操作数之间的关系,例如是将变量放在寄存器中还是放在内存中等,常用的如下:在内存中等,常用的如下:限定字符限定字符 描述描述a a、b b、c c、d d、s s、DD具体的一个寄存器具体的一个寄存器 q q、r r、A A混合的寄存器混合的寄存器mm、o o、V V、p p内存内存g g、X X寄存器或内存寄存器或内存I I、J J、NN、i i、n n立即数立即数=、+操作数类型操作数类型内嵌汇编示例内嵌汇编示例n

31、n例例1 1 int main(void)int main(void)int result=2;int result=2;int input=1;int input=1;_asm_ _volatile_(addl%1,%0:=r(result):_asm_ _volatile_(addl%1,%0:=r(result):r(input);r(input);printf(%dn,result);printf(%dn,result);return 0;return 0;这段内嵌汇编原本的目的是输出这段内嵌汇编原本的目的是输出1+2=31+2=3的结果,也就是将的结果,也就是将inputinput变

32、量的值与变量的值与resultresult变量的值相加之后再存入变量的值相加之后再存入resultresult中。可中。可以看到在汇编语句模板中的以看到在汇编语句模板中的%1%1与与%0%0分别代表分别代表inputinput与与resultresult变变量,而量,而“=r”“=r”与与“r”“r”则表示两个变量在汇编中应该对应则表示两个变量在汇编中应该对应两个寄存器,两个寄存器,“=”“=”表示表示resultresult是输出变量。然而实际运行是输出变量。然而实际运行后发现结果实际上是后发现结果实际上是2 2。这是为什么呢?。这是为什么呢?内嵌汇编示例内嵌汇编示例n n我们用我们用(ob

33、jdump-j.text S(objdump-j.text S 可执行文件名可执行文件名)这样的命令来查这样的命令来查看编译生成后的代码发现这段内嵌汇编经看编译生成后的代码发现这段内嵌汇编经GCCGCC翻译后所对翻译后所对应的应的AT&TAT&T汇编是:汇编是:movl$0 x2,0 xfffffffc(%ebp)movl$0 x2,0 xfffffffc(%ebp)movl$0 x1,0 xfffffff8(%ebp)movl$0 x1,0 xfffffff8(%ebp)movl 0 xfffffff8(%ebp),%eax movl 0 xfffffff8(%ebp),%eax addl%

34、eax,%eax addl%eax,%eax movl%eax,0 xfffffffc(%ebp)movl%eax,0 xfffffffc(%ebp)前两句汇编分别是为前两句汇编分别是为resultresult和和inputinput变量赋值。变量赋值。inputinput为输入为输入型变量,而且需要放在寄存器中,型变量,而且需要放在寄存器中,GCCGCC给它分配的寄存器给它分配的寄存器是是%eax%eax,在执行,在执行addladdl之前之前%eax%eax的内容已经是的内容已经是inputinput的值。读的值。读入入inputinput后执行后执行addladdl,显然,显然addl%

35、eax,%eax addl%eax,%eax 的值不对。的值不对。内嵌汇编示例内嵌汇编示例n n之所以会出现以上的结果是因为:之所以会出现以上的结果是因为:使用使用“r”“r”限制的输入变量,限制的输入变量,GCCGCC先分配一个寄存先分配一个寄存器,然后将值读入寄存器,最后用该寄存器替换器,然后将值读入寄存器,最后用该寄存器替换占位符占位符 使用使用“r”“r”限制的输出变量,限制的输出变量,GCCGCC会分配一个寄存会分配一个寄存器,然后用该寄存器替换占位符,但是在使用该器,然后用该寄存器替换占位符,但是在使用该寄存器之前并不将变量值先读入寄存器,寄存器之前并不将变量值先读入寄存器,GCC

36、GCC认认为所有输出变量以前的值都没有用处,不读入寄为所有输出变量以前的值都没有用处,不读入寄存器,最后存器,最后GCCGCC插入代码,将寄存器的值写回变插入代码,将寄存器的值写回变量量 因为第二条,这样内嵌汇编指令不能奏效,因为因为第二条,这样内嵌汇编指令不能奏效,因为在执行在执行addladdl之前之前resultresult的值没有被读入寄存器的值没有被读入寄存器内嵌汇编示例内嵌汇编示例n n修改后的指令如下修改后的指令如下 :int main(void)int main(void)int result =2;int result =2;int input =1;int input =1

37、;_asm_ _volatile_(addl%2,%0:=r(result):r(result),m(input);_asm_ _volatile_(addl%2,%0:=r(result):r(result),m(input);printf(%dn,result);printf(%dn,result);return 0;return 0;这段内嵌汇编所对应的这段内嵌汇编所对应的AT&TAT&T汇编如下:汇编如下:movl$0 x2,0 xfffffffc(%ebp)movl$0 x2,0 xfffffffc(%ebp)movl$0 x1,0 xfffffff8(%ebp)movl$0 x1,

38、0 xfffffff8(%ebp)movl 0 xfffffffc(%ebp),%eax movl 0 xfffffffc(%ebp),%eax addl 0 xfffffff8(%ebp),%eax addl 0 xfffffff8(%ebp),%eax movl%eax,0 xfffffffc(%ebp)movl%eax,0 xfffffffc(%ebp)内嵌汇编示例内嵌汇编示例n n上面的代码应该可以正常工作,因为我们知道上面的代码应该可以正常工作,因为我们知道%0%0和和%1%1都和都和resultresult相关,相关,应该使用同一个寄存器,而且事实上在实际结果中应该使用同一个寄存器

39、,而且事实上在实际结果中GCCGCC也确实是使用也确实是使用了同一个寄存器了同一个寄存器eaxeax,所以可以得到正确的结果,所以可以得到正确的结果3 3。但是为了更保险起。但是为了更保险起见,为了确保见,为了确保%0%0与与%1%1与同一个寄存器关联我们可以使用如下的方法:与同一个寄存器关联我们可以使用如下的方法:int main(void)int main(void)int result =2;int result =2;int input =1;int input =1;_asm_ _volatile_(addl%2,%0:=r(result):0(result),m(input);_a

40、sm_ _volatile_(addl%2,%0:=r(result):0(result),m(input);printf(%dn,result);printf(%dn,result);return 0;return 0;在上面的程序中我们使用了占位符在上面的程序中我们使用了占位符“0”“0”表示表示%0%0与与%1%1是使用的同一个是使用的同一个寄存器,这样就确保了程序的正确性。寄存器,这样就确保了程序的正确性。内嵌汇编示例内嵌汇编示例n n例例2 2 int main(void)int main(void)int count=3;int count=3;int value=1;int va

41、lue=1;int buf10;int buf10;asm(asm(cld nt cld nt rep nt rep nt stosl stosl :c(count),a(value),D(buf);:c(count),a(value),D(buf);printf(%d%d%dn,buf0,buf1,buf2);printf(%d%d%dn,buf0,buf1,buf2);经GCC翻译后所对应的AT&T汇编是:movl 0 xfffffff4(%ebp),%ecxmovl 0 xfffffff0(%ebp),%eaxlea 0 xffffffb8(%ebp),%edicld repz stos

42、%eax,%es:(%edi)在这里count、value和buf是三个输入变量,它们都是C程序中的变量,“c”、“a”和“D”表示这三个输入值分别被存放入寄存器ECX、EAX与EDI;“cld rep stosl”是需要执行的汇编指令;而“%ecx、%edi”表示这两个寄存器在指令中被改变了。这段内嵌汇编要做的就是向buf中写count个value值。内嵌汇编示例内嵌汇编示例n n例例3 3 int main(void)int main(void)int input,output,temp;int input,output,temp;input=1;input=1;_asm_ _volati

43、le_ (movl$0,%eax;nt _asm_ _volatile_ (movl$0,%eax;nt movl%eax,%1;nt movl%eax,%1;nt movl%2,%eax;nt movl%2,%eax;nt movl%eax,%0;nt movl%eax,%0;nt :=m(output),=m(temp):=m(output),=m(temp):r(input):r(input):eax);:eax);printf(%d%dn,temp,output);printf(%d%dn,temp,output);return 0;return 0;内嵌汇编示例内嵌汇编示例n n这段

44、内嵌汇编经由这段内嵌汇编经由GCCGCC转化成的汇编代码如下:转化成的汇编代码如下:movl$0 x1,0 xfffffffc(%ebp)movl$0 x1,0 xfffffffc(%ebp)mov 0 xfffffffc(%ebp),%edx mov 0 xfffffffc(%ebp),%edx mov$0 x0,%eax mov$0 x0,%eax mov%eax,0 xfffffff4(%ebp)mov%eax,0 xfffffff4(%ebp)mov%edx,%eax mov%edx,%eax mov%eax,0 xfffffff8(%ebp)mov%eax,0 xfffffff8(%

45、ebp)可以看到,由于可以看到,由于inputinput、outputoutput、temptemp都是程序局部整型数变量,于是都是程序局部整型数变量,于是它们实际上是存放在堆栈中的,也就是内存中的某个部分。其中它们实际上是存放在堆栈中的,也就是内存中的某个部分。其中outputoutput和和temptemp是输出变量,而且是输出变量,而且“=m”“=m”表明它们应该在内存中,表明它们应该在内存中,inputinput是输入变量,是输入变量,“r”“r”表明它应存放在寄存器中,于是首先把表明它应存放在寄存器中,于是首先把1 1存入存入inputinput变量,然后将变量的值复制给了变量,然后将变量的值复制给了edxedx寄存器,在这里我们可以看到内寄存器,在这里我们可以看到内嵌汇编中使用了破环描述符嵌汇编中使用了破环描述符“eax”“eax”,这是告诉编译器在程序中,这是告诉编译器在程序中eaxeax寄寄存器已被使用,这样编译器为了避免冲突会将输入变量存放在除存器已被使用,这样编译器为了避免冲突会将输入变量存放在除eaxeax以以外别的寄存器中,如像我们最后看到的外别的寄存器中,如像我们最后看到的edxedx寄存器。寄存器。

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

当前位置:首页 > 教育专区 > 小学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁