AT&T匯編和8086匯編語言雖然兩者很相似,但是還是不能根據8086的語法規則來讀AT&T匯編的吧,所以還是要看看AT&T匯編的語法規則,因為在讀內核代碼時,跟硬件打交道的部分代碼是用AT&T匯編編寫的,所以不可避免的會遇到AT&T匯編,下面先來看看AT&T匯編的語法規則吧。
一、 大小寫
INTEL格式的指令使用大寫字母,而AT&T格式的使用小寫字母。
例:
INTEL AT&T
MOV EAX,EBX movl %ebx,%eax
二、 操作數賦值方向
在INTEL語法中,第一個表示目的操作數,第二個表示源操作數,賦值方向從右向左。
AT&T語法第一個為源操作數,第二個為目的操作數,方向從左到右,合乎自然。
例:
INTEL AT&T
MOV EAX,EBX movl %ebx,%eax
三、前綴
在 INTEL 語法中寄存器和立即數不需要前綴;AT&T 中寄存器需要加前綴“%” ;立即數
需要加前綴“$” 。
例:
INTEL AT&T
MOV EAX,1 movl $1,%eax
符號常數直接引用,不需要加前綴,如:movl value , %ebx,value為一常數;在符
號前加前綴$表示引用符號地址, 如movl $value, %ebx,是將value的地址放到 ebx中。
總線鎖定前綴“lock” :總線鎖定操作。 “lock”前綴在Linux 核心代碼中使用很多,特
別是SMP代碼中。當總線鎖定后其它CPU不能存取鎖定地址處的內存單元。
遠程跳轉指令和子過程調用指令的操作碼使用前綴“l“,分別為 ljmp,lcall,與之
相應的返回指令偽lret。
例:
INTEL AT&T
CALL FAR SECTION:OFFSET lcall $secion:$offset
JMP FAR SECTION:OFFSET ljmp $secion:$offset
RET FAR SATCK_ADJUST lret $stack_adjust
四、間接尋址語法
INTEL 中基地址使用“[” 、“]” ,而在 AT&T 中使用“(”、“)” ;另外處理復雜操作數的
語法 也 不同 , INTEL 為 Segreg:[base+index*scale+disp] , 而在 AT&T 中為
%segreg:disp(base,index,sale),其中segreg,index,scale,disp都是可選的,在指定
index而沒有顯式指定Scale的情況下使用默認值 1。Scale和 disp不需要加前綴“&” 。
INTEL AT&T
Instr
foo,segreg:[base+index*scale+disp]
instr
%segreg:disp(base,index,scale),foo
五、 后綴
AT&T 語法中大部分指令操作碼的最后一個字母表示操作數大小, “b”表示 byte(一個
字節) ;“w”表示 word(2 個字節) ;“l”表示 long(4 個字節) 。INTEL 中處理內存操作數
時也有類似的語法如:BYTE PTR、WORD PTR、DWORD PTR。
例:
INTEL AT&T
mov al, bl movb %bl,%al
mov ax,bx movw %bx,%ax
mov eax, dword ptr [ebx] movl (%ebx), %eax
在 AT&T 匯編指令中,操作數擴展指令有兩個后綴,一個指定源操作數的字長,另一個
指定目標操作數的字長。AT&T 的符號擴展指令的為“movs” ,零擴展指令為“movz” (相應
的 Intel指令為“movsx”和“movzx”) 。因此, “movsbl %al,%edx”表示對寄存器 al 中的
字節數據進行字節到長字的符號擴展,計算結果存放在寄存器edx中。下面是一些允許的操
作數擴展后綴:
bl: 字節->長字
bw: 字節->字
wl: 字->長字
跳轉指令標號后的后綴表示跳轉方向, “f” 表示向前 (forward) , “b” 表示向后 (back) 。
例:
jmp 1f
jmp 1b
原文鏈接:https://blog.csdn.net/bigloomy/article/details/6581754