X86汇编的乘除法以及栈的定义使用

寄存器向下兼容,保留了ax,bx等寄存器

Screenshot_20220109_222051.png

乘除法

乘法:mul + reg/mem

除法:div + reg/mem

它们只有一个操作数,所以会使用特定的寄存器,来保存另外一个参与计算的数

如果是8位乘8位的乘法,乘积的高8位保存在ah寄存器,低8位保存在al寄存器;如果是16位的乘法,高16位存在dx寄存器,低16位存在ax寄存器;

乘法的结果也会影响CF标志位

Screenshot_20220109_222449.png

div指令后面的数是除数,被除数事先保存到ax寄存器或者dx:ax寄存器

Screenshot_20220109_222852.png

mul和div指令对应的操作数都是无符号的,也就是不能处理负数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
; 8位乘法
mov al, 0xf0
mov ah, 0x02
mul ah
; 16位乘法
mov ax, 0xf000
mov bx, 0x0002
mul bx
; 16位除法
mov ax, 0x0004
mov bl, 0x02
div bl
; 32位除法
mov dx, 0x0008
mov ax, 0x0006
mov cx, 0x0002
div cx
; 循环以及补0
jmp $
times 510-($-$$) db 0
db 0x55, 0xaa

定义代码段:CS寄存器保存代码段的基地址,IP保存相对于基地址的偏移

栈也是这样定义的,其基准地址是SS,偏移地址是SP

数据段和代码段,是从内存低处向高处行进的,地址是增长的。对于栈来说,push操作会让SP减小,pop操作会让SP增大。通常来说,我们可以把SS设置为0x0000,那么进行push操作时:

Screenshot_20220109_224305.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
; 设置SS寄存器
mov bx, 0x0000
mov ss, bx
; 设置sp寄存器
mov sp, 0x0000
; ax压入栈
push ax
; ax弹出栈
pop ax

; 循环以及补0
jmp $
times 510-($-$$) db 0
db 0x55, 0xaa

Screenshot_20220109_224515.png