AT&T匯編指令學習(GCC)
-
寄存器命名原則:
相比inter語法,AT&T語法格式要求所有的寄存器都必須加上取值符"%". -
操作碼命令格式:
-
源/目的操作數順序:
Intel語法格式中命令表示格式為:"opcode dest, src"; "操作碼 目標, 源"
AT&T語法格式表示為:"opcode src, dest"; "操作碼 源, 目標" -
操作數長度標識:
在AT&T語法中,通過在指令后添加后綴來指明該指令運算對象的尺寸.
后綴 'b' 指明運算對象是一個字節(byte)
后綴 'w' 指明運算對象是一個字(word)
后綴 'l' 指明運算對象是一個雙字(long)
Intel語法中指令'mov'在AT&T語法必須根據運算對象的實際情況寫成:'movb','movw'或'movl'。
注:若在AT&T中省略這些后綴,GAS將通過使用的寄存器大小來猜測指令的操作數長度. -
另外,
'FAR'不是GAS的關鍵字,因此對far的call或jmp指令須加前綴 'l', 'far call'要寫成 'lcall' , 'far jmp' 要寫成 'ljmp' , 'ret far' 寫成 'lret'。
-
-
常數/立即數的格式:
在AT&T語法中對立即數,須在其前加前綴 $ 來指明,而Inter語法則不需要。
另外, 在常數前也必須加一個前綴字符 * ,而Inter語法則也是不需要的。 -
內存尋址方式:
在Intel語法中,使用下面格式來表示存儲器尋址方式:
SECTION:[BASE + INDEX*SCALE + DISP];
段:[基地址+變址*比例因子+偏移量]
BASE是基地址索引寄存器(可以是任一通用寄存器),
INDEX是變址寄存器(除ESP外的任一通用寄存器),
SCALE是變址寄存器的比例常數,
DISP是基址/變址寄存器的位移量。
AT&T語法則使用不同的格式來表示尋址方式:
SECTION:DISP(BASE, INDEX, SCALE);
段:偏移量(基地址,變址,比例因子) -
標號 & 標識符:
所有的標號必須以一個字母,點或下划線開始,標號后加一個冒號表示標號的結束。
局部標號使用數字0-9后跟一個冒號,使用局部標號時要在數字后跟一個字符'b'(向后引用)或字符'f'(向前引用)。因為只能使用數字0-9作為局部標號名,所以最多只能定義10個局部標號.一個標識符能給它賦於一個值。(如:'TRUE=1', 或者使用 .set 或 .equ 指令)。 -
基本的行內匯編格式:
asm("statements");
例如:asm("nop"); asm("movl %eax,%ebx");
asm 和 __asm__是完全一樣的.
如果有多行匯編,則每一行都要加上 "\n\t" -
擴展的行內匯編格式:
asm ( "statements" : output_regs : input_regs : clobbered_regs);
冒號后的語句指明輸入,輸出和被改變的寄存器. -
IA32整數寄存器:
-
常用指令:
- 數據傳送指令:move,push,pop;
- 加載有效地址指令:leal;
- 一元操作指令:inc(加1),dec(減1),neg(取負),not(取補);
- 二元操作指令:add,sub,imul,idivl(有符號除法),xor,or,and;
- 移位指令:sal(左移),shl,sar(算數右移),shr(邏輯右移);
- 跳轉指令:jmp,je,jne,js,jns,jg,jl,ja,jb,jbe...
-
條件碼寄存器(單個bit):
cf(進位標志),zf(零標志),sf(符號標志),of(溢出標志)...
訪問條件碼指令:cmp,test,set...t = a + b; cf: (unsigned) t < (unsigned) a;//無符號溢出 zf: t == 0;//零 sf: t < 0;//負數 of: (a < 0 == b < 0) && (t < 0 != a < 0)//有符號溢出