您的位置:首页 > 其它

(转载)AT&T汇编与Intel汇编的一些区别

2010-01-11 20:35 232 查看
AT&T汇编与Intel汇编的一些区别

前些天在看kernel的i386的bootsect.S文件,该文件在1.11版本的时候还是用intel汇编的格式写的,不过我又读了2.4.20的
bootsect.S,里头却是AT&T的格式,不知道这个改动是在哪个版本发生的。由于很久没有接触过汇编,再加上bootsect.S中的内
容涉及很多的底层,例如硬盘的读取,int中断等等;让我花了非常多的时间才搞清楚了bootsect.S的工作原理。

AT&T的汇编和Intel的汇编主要是语法格式的区别,然后是指令的区别。AT&T的汇编指令和Intel的汇编指令大体相同,但是在
一些地方有些微的区别。我们先来看AT&T和Intel的格式差别,这些在网上很容易搜到,就当整理记录吧。

AT&T与Intle的汇编格式区别:

1)AT&T汇编语言中源操作数和目的操作数的位置与Intel的语法正好相反。

原本我没有太在意这个,因为在遇到MOV指令的时候,AT&T的格式反而更符合阅读习惯,但是在遇到subw
%bx,%ax这个语句的时候,曾经让我困惑了很久,最后才反应过来,源操作数和目的操作数位置相反了;刚开始很不适应,因为sub这些指令我觉得
Intel的格式更符合习惯(还有其他的cmp等等)。

2)前缀。AT&T中所有立即数前缀$:$ 7,寄存器前要加%:%eax(据说后者是gnu的as的特性,而不是AT&T的)

3)后缀。AT&T中所有的操作码多有后缀:”b” “w” “l”,Intel使用的是”byte ptr”、”word
ptr”。如movb,movw,movl。分别进行8位(byte)、16位(word)和32位(long)的数据传送。顺道提一下,如果mov后面
没有加后缀,gnu的as程序将根据操作数中的寄存器补上相应的后缀。

4)间接寻址的表示:Intel的间接寻址用”[]”,而AT&T用”()”。

AT&T: movw 4(%bp), %dx

Intel: mov dx,[bp+4]

你还有可能见到以下两种:

AT&T: _var( , %ebx , 4)

Intel: [_var + ebx * 4]

AT&T: _array(%eax, %ebx, 8 )

Intel: [%eax + %ebx * 8 + _array]

上面的两种其实是一样的,只是前者省略了第一个参数而已。

在清楚上面几个差别清楚之后,只要你能看的懂Intel的汇编,看AT&T的基本也没什么问题了。事实上,我是Intel的和AT&T汇
编对照着看的,尤其是在看AT&T的某个地方被“一叶障目”的时候,再看看Intel的汇编很有可能会恍然大悟。

然后就是指令上的一些差别了。AT&T的汇编指令和Intel的基本一致,但是在以下地方需要注意一下:

1)在AT&T汇编指令中,直接远跳转/调用的指令格式是

lcall/ljmp $SECTION,$OFFSET”

同样,远程返回的指令是“lret $STACK-ADJUST”;而在Intel格式中,相应的指令分别为

call/jmp far SECTION:OFFSET



ret far STACK-ADJUST

。其实和mov这些指令的后缀差不多,只是lcall是前缀。

2)一些类型转换指令。转换关系如下(均用符号位扩展):

a. cbw cbtw :%al->%ax

b. cwde cwtl :%ax->%eax

c. cwd cwtd :%ax->%dx : %ax

d. cdq cltd :%eax->%edx : %eax

整个bootsect.S并不难看懂,网上有很多的资料。主要是你可能得了解一些关于硬盘的知识,例如硬盘参数表的存放位置、硬盘的读取顺序等;然后是
Intel提供的中断向量:int xxH
;还有就是你的汇编功底了,只要你对微机原理还有稍许印象,再找一个汇编指令手册就行,通常你的微机原理课本就可以胜任了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: