本节咱们介绍下intel汇编语法和at&t汇编语法的区别。
以上表中未列出这两种语法在内存寻址方面的差异,个人觉得区别还是很大的,下面单独说说。
在Intel语法中,立即数就是普通的数字,如果让立即数成为内存地址,需要将它用中括号括起来,“[立即数]”这样才表示以“立即数”为地址的内存。
而AT&T认为,内存地址既然是数字,那数字也应该被当作内存地址,所以,数字被优先认为是内存地址,也就是说,操作数若为数字,则统统按以该数字为地址的内存来访问。这样,立即数的地位比较次要了,如果想表示成单纯的立即数,需要额外在前面加个前缀$。
无论是哪种汇编语言风格,都要有访问内存的能力,这就是内存寻址。
咱们之前学习了Intel汇编语法中的很多寻址方式,就内存寻址来说,有直接寻址,基址寻址,变址寻址,基址变址寻址。也可能是习惯了的原因,我个人觉得intel语法真的很直白,容易理解,尤其是在和AT&T的内存寻址相比较之后……
而在AT&T中的内存寻址还是挺独特的,它的内存寻址有固定的格式:
segreg(段基址):base_address(offset_address,index,size)
该格式对应的表达式为:
segreg(段基址):base_address+ offset_address+ index*size。
此表达式的格式和intel 32位内存寻址中的基址变址寻址类似,intel的格式:
segreg:[base+index*size+offset]
不过与intel不同的是,AT&T地址表达式的值是内存地址,直接被当做是内存来读写,而不是普通数字。
看上去格式有些怪异,但其实这是一种“通用”格式,格式中短短的几个成员囊括了它所有内存寻址的方式,任意一种内存寻址方式,其格式都是这个通用格式的子集,都是格式中各种成员的组合。下面介绍下这些成员项。
base_address是基地址,可以为整数,变量名,可正可负。
offset_address是偏移地址,index是索引值,这两个必须是那8个通用寄存器之一。
size是个长度,只能是1、2、4、8(intel语法中也是只能乘以这4个数)。
下面看看内存寻址中有哪些方式,注意,这些方式都是上面通用格式的一部分。
直接寻址:此寻址中只有base_address项,即后面括号中的东东全不要,base_address便为内存啦,比如movl $255,0xc00008F0,或者用变量名:mov $6,var。
寄存器间接寻址:此寻址中只有offset_address项,即格式为(offset_address),要记得,offset_address只能是通用寄存器。寄存器中是地址,不要忘记格式中的圆括号。如mov (