1 :加法
1.1 add source ,destination
ADD指令可以将8,16,32位指令相加。其中b(用于字节),w(用于字),或者l(用于汉字)
使用add指令特别关注溢出问题,addb超过255就会溢出,标志位设置为1,addw 超过65525就会溢出,设置标志位为1.有时 候程序员不清楚何时溢出,此时溢出标志就很重要了 .
.section .data
output:
.asciz " THe result id %d\n"
.section .text
.globl _start
_start:
movl $-1590876934 ,%ebx
movl $-1259230143, %eax
addl %eax,%ebx
jo over
pushl %ebx
call printf
add $8,%esp
pushl $0
call exit
over:
pushl $0
pushl $output
call printf
add $8 ,%esp
call exit
jo 是判读指令,溢出后程序跳转到over,因此如果溢出,则输出为0
1.2 adc source ,destination
处理特别大的数据时,一个32位的寄存器不能存放,则分开至2个或者多个32位寄存器,具体看例程:
.section .data
data1:
.quad 7252051615 #显示64位带符号的数值
data2:
.quad 5732348928
output:
.asciz " THe result is %d\n"
.section .text
.globl _start
_start:
movl data1,%ebx #低32位
movl data1+4 ,%eax #高32位
movl data2,%edx
movl data2+4 ,%ebx
addl %ebx,%edx #低位寄存器加法
adcl %eax ,%ecx #高位寄存器加法
pushl %ecx #高64位
pushl %edx #低64位
push $output
call printf
addl $12,%esp
pushl $0
call exit
2. 减法
sub source,destination(适用于低位寄存器)
其中的destination 的值中减去source的值,结果保存在destination
sbb source,destination(适用于高位寄存器)
其中的destination 的值中减去source的值,结果保存在destination
例程:
.section .data
data1:
.quad 72520551615
data2:
.quad 5732348928
output:
.asciz "The result is %d\n"
.section .text
.globl _start
_start:
nop
movl data1,%ebx
movl data1+4,%eax
movl data2 ,%edx
movl data2+4 ,%ecx
subl %ebx,%edx
sbbl %eax,%ecx
pushl %ecx
pushl %edx
push $output
call printf
addl $12,%esp
pushl $0
call exit
运行结果:
递增和递减指令
inc destination(递增)
dec destination(递减)
3.乘法
3.1 mul sourcce(无符号整数)
用于两个无符号的整数相乘,source可以是8,16,32位寄存器或者内存值。mul的目标数是隐含的,乘法操作中另一个操作数必须存放在AL,AX或EAX寄存器中
.section .data
data1:
.int 315814
data2:
.int 165432
result:
.quad 0
output:
.asciz "The result is %qd\n"
.section .text
.globl _start
_start:
nop
movl data1,%eax
mull data2
movl %eax ,result
movl %edx,result+4
pushl %edx
pushl %eax
push $output
call printf
addl $12,%esp
pushl $0
call exit
第17 行代码为何选择edc寄存器。对于32位源值, 目标位置使用64位EDX: EAX寄存器对,高位双字存储在EDX寄存器中才低位双字在EAX寄存器中。当使用MUL的16位或者32位版本时,如果在EDX ( 或者DX)寄器中存储着数据,那么一定要把数据保存到其他位置。
3.2 imul 带符号整数操作
imul source (其行为和mul完全一样)
imul source destination (结果被限制在单一目标寄存器,小心溢出)
imul multiplier, source ,destination(multiplier * source结果存在destinatiuon )
4 除法
4.1 无符号除法
div divisor
在执行DIV指令之前,被除数必须已经存储到了AX寄存器(对于16位值)、DX:AX寄存器对(对于32位值)或者EDX:EAX寄存器对(对于64位值)。允许的除数的最大值取决于被除数的长度。对于16位被除数,除数只能是8位;对于32位被除数,除数只能是16位;对于64位被除数,除数只能是32位。除法操作的结果是两个单独的数字:商和余数。这两个值都存储在被除数值使用的相同寄存器中。
例程:
.section .data
dividend:
.quad 8335
divisor:
.int 25
quotient:
.int 0
remainder:
.int 0
output:
.asciz "The quotient is %d ,and the remainder is %d\n"
.section .text
.globl _start
_start:
nop
movl dividend ,%eax
movl dividend+4 ,%edx
divl divisor
movl %eax,quotient
movl %edx,remainder
pushl quotient
push $output
call printf
addl $12,%esp
pushl $0
call exit
运行结果
4.2 有符号除法
idiv divisor
对于带符号整数的除法,余数的符号总是与被除数的符号相同