- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
ATamp;T的汇编格式.pdf
内联汇编 2007-12-06 14:32:27
分类: LINUX
ATT 的汇编格式
一 基本语法
语法上主要有以下几个不同.
★ 寄存器命名原则
ATT: %eax Intel: eax
★源/ 目的操作数顺序
ATT: movl %eax,%ebx Intel: mov ebx,eax
★常数/立即数的格式
ATT: movl $_value,%ebx Intel: mov eax,_value
把_value 的地址放入 eax 寄存器
ATT: movl $0xd00d,%ebx Intel: mov ebx,0xd00
★ 操作数长度标识
ATT: movw %ax,%bx Intel: mov bx,ax
★寻址方式
ATT: immed32(basepointer,indexpointer,indexscale)
Intel: [basepointer + indexpointer*indexscale + imm32)
Linux 工作于保护模式下,用的是32位线性地址,所以在计算地址时不用考虑 segment:offset
的问题.上式中的地址应为:
imm32 + basepointer + indexpointer*indexscale
下面是一些例子:
★直接寻址
ATT: _booga ; _booga 是一个全局的 C 变量
注意加上$是表示地址引用,不加是表示值引用.
注:对于局部变量,可以通过堆栈指针引用.
Intel: [_booga]
★寄存器间接寻址
ATT: (%eax)
Intel: [eax]
★变址寻址
ATT: _variable(%eax)
Intel: [eax + _variable]
ATT: _array(,%eax,4)
Intel: [eax*4 + _array]
ATT: _array(%ebx,%eax,8)
Intel: [ebx + eax*8 + _array]
二 基本的行内汇编
·基本的行内汇编很简单,一般是按照下面的格式:
asm(statements);
例如:asm(nop); asm(cli);
·asm 和 __asm__是完全一样的.
·如果有多行汇编,则每一行都要加上 \n\t
例如:
asm( pushl %eax\n\t
movl $0,%eax\n\t
popl %eax);
实际上 gcc 在处理汇编时,是要把 asm(...)的内容打印到汇编文件中,所以格式控制字符是
必要的.
再例如:
asm(movl %eax,%ebx);
asm(xorl %ebx,%edx);
asm(movl $0,_booga);
在上面的例子中,由于我们在行内汇编中改变了 edx 和 ebx 的值,但是由于 gcc 的特殊的处
理方法,即先形成汇编文件,再交给 GAS 去汇编,所以 GAS 并 不知道我们已经改变了 edx 和
ebx 的值,如果程序的上下文需要 edx 或 ebx 作暂存,这样就会引起严重的后果.对于变量
_booga 也存在一样的问题. 为了解决这个问题,就要用到扩展的行内汇编语法.
三 扩展的行内汇编
扩展的行内汇编类似于 Watcom.
基本的格式是:
asm ( statements : output_regs : input_regs : clobbered_regs);
clobbered_regs 指的是被改变的寄存器.
下面是一个例子(为方便起见,我使用全局变量):
int count=1;
int value=1;
int buf[10];
void main()
{
asm(
cld \n\t
rep \n\t
stosl
:
: c (count), a (value) , D (buf[0])
: %ecx,%edi );
}
得到的主要汇编代码为:
movl count,%ecx
movl value,%eax
movl buf,%edi
#APP
cl
rep
stosl
#NO_APP
cld,rep,stos 就不用多解释了.这几条语句的功能是向 buf 中写上 count 个 value 值.冒号后
的语句指明输入,输出和被改变的寄存器.通 过冒号以后的语句,编译器就知道你的指令需要
和改变哪些寄存器,从而可以优化寄存器的分配.
其中符号c(count)指
原创力文档


文档评论(0)