這一節介紹如何在編語言中上使用整數運算,包括加法、減法、乘法和除法。
add src, dest
其中src可以是立即數值、內存地址、寄存器。dest可以是寄存器或內存中的值,不能同時使用內存地址作為源和目標。結果存放在dest中。和其他GNU彙編指令一樣,需要在add結尾添加b、w、l來指定操作數長度。如果沒有使用整個寄存器,就要確保零填充目標寄存器,使得寄存器高位沒有內容。add指令可以對所有帶符號的整數執行加法操作。
在執行整數想加時,應該注意EFLAGS寄存器,當在無符號數做加法操作造成進位(結果大於允許的最大值)情況時,進位標誌會被置為1。在有符號整數出現溢出情況時(結果小於允許最小負值或大於允許最大正值),溢出標誌會被設置為1。下面示例演示無符號整數加法進位的情況:
#add1.s
.section .text
.globl _start
_start:
nop
movl $0, %ebx
movb $240, %bl
movb $20, %al
# movb $2, %al
addb %al, %bl
jc over
movl $1, %eax
int $0x80
over:
movl $1, %eax
movl $0, %ebx
int $0x80
如果加法操作造成進位,則把進位標誌設置為1,程序返回0,否則返回加法的結果。我們分別修改上述代碼使其造成進位和不進位(取消代碼註釋行且註釋上一行代碼),分別make、執行結果如下:
$ make
as -o add1.o add1.s --gstabs
ld -o add add1.o
$ ./add
$ echo $?
0
$ vim add1.s//修改代碼,使其不進位
$ make clean;make
rm -f add1.o add *~
as -o add1.o add1.s --gstabs
ld -o add add1.o
$ ./add
$ echo $?
242 //不進位時程序返回加法結果
在執行無符號整數加法時,總應該檢查進位標誌,如果知道輸入值界限,就可以不必檢查進位標誌。 在處理有符號整數,不需要判斷進位標誌,而是需要注意溢出標誌,當結果溢出正值或負值界限時,這個標誌會被設置為1。 使用adc指令可以處理大於雙字數據長度的加法。
減法操作和加法操作類似,減法指令是sub,格式類似加法指令:
sub src, dest
減法指令也需要在sub末尾添加b、w、l。和add指令類似,sub指令也會修改EFLAGS寄存器的位。 使用進位標誌確定無符號整數減法產生負數結果的情況。有符號數的減法需要依靠溢出標誌來判斷數據長度界限的情況。
sbb指令類似adc指令,可以使用進位情況幫助執行大的無符號整數的減法操作。
遞增遞減指令
乘法指令 mul指令用於兩個無符號整數相乘,格式如下:
mul src
src可以是8、16、32位寄存器或內存值。使用GNU彙編器時,命令助記符結尾加上正確長度字符。
該指令的目標操作數是隱含的。根據元操作數的值長度,乘法操作使用另一個操作數必須放在al、ax、eax寄存器中。由於乘法可能產生很大的值,所以mul指令目標位置必須是元操作數的兩倍長度。下表是無符號整數乘法的需求:
源操作數長度(位) |
目標操作數
|
目標位置
|
8
|
AL
|
AX
|
16
|
AX
|
DX:AX
|
32
|
EAX
|
EDX:EAX
|
imul命令可以進行有符號整數的乘法。 imul指令有三種指令格式:
imul src #這種指令格式和mul的使用一樣
imul src,dest #允許指定eax之外的目標操作數
imul multipler, src, dest #multipler是立即值
無符號除法指令:div divisor
有符號除法指令:idiv divisor
divisor是隱含被除數要除以的值。
在平時編寫高級語言時,都知道乘法和除法是很消耗處理器時間的,有些時候會使用移位來代替乘除法。在彙編語言中一樣,也可以使用移位,移位指令提供基於2的乘方的乘法和除法。把二進制數字左移1就是乘以2,左移2位就是乘以4,移位操作比執行二進制乘法操作要快得多。
sal dest #左移一位,等同於乘以2
sal %cl, dest #左移cl寄存器中的數
sal shifter, dest #左移shifter值指定的數
左移指令可以對無符號和有符號整數執行向左移位指令,空位補0,超出數據長度的位首先存放在進位標誌中,在下一次移位操作中被丟棄。
向右移位指令:shr和sar
邏輯操作指令
布爾邏輯操作:add、not、or、xor
and、or、xor指令格式一樣:
and src, dest
not指令使用單一操作數。
清空寄存器最高效的方式就是使用xor指令對寄存器和他本身進行異或操作。
test指令最常見的用途是檢查EFLAGS寄存器中的標誌。