本篇以及所有汇编复习内容均根据白洪欢《汇编语言程序设计》整理
这本书写的很详细,很好。可惜绝版了。
汇编指令
数据传送指令
mov指令
语法:mov ax, bx
意义:把bx的值传递给ax
标志位:不影响
注意点:
1.操作数不能都为变量,
2.操作数类型必须一致,
3.不能把常数赋值给段寄存器,
4.不允许对cs赋值,
5.不能用段寄存器赋值段寄存器
以下均为错误指令:
mov byte ptr ds:[108Ch],byte ptr ds:[1000h]
;内存赋值给内存。
mov ds, 1000h
;常数赋值段地址.
mov ax, byte ptr ds:[bx]
;操作数类型不一致,
赋值段地址只能用间接赋值,可以是寄存器或者变量
push指令
语法:push ax
意义:将一个操作数压入堆栈,sp=sp-2
标志位:不影响
注意点:
1.压入堆栈的寄存器或者变量必须是16位,比如
push ax
;16位寄存器
push word ptr ds:[bx]
;16位变量
2.不能push常数
pop指令
语法:pop ax
意义:堆栈弹出一个数,赋值给操作数,sp=sp+2
标志位:不影响
注意点:
1.操作数必须16位
2.pop操作数不能是cs
xchg指令
语法:xchg ax, bx
意义:交换两个操作数的值
标志位:不影响
注意点:操作数中不能有段寄存器
地址传送指令
lea指令
语法:lea bx , ds:[10F8h]
意义:获取右边操作数的偏移地址,放入bx中
标志位:不影响
lds指令
语法:lds bx, es:[10F0h]
意义:以dword(8个16进制位)类型获取右边地址所指的内容(可以是一个远指针,分为段地址和偏移地址),偏移地址(低4位)放入寄存器中,段地址(高4位)放入ds中
相当于mov bx, word ptr es:[10F0h],mov ds word ptr es:[10F0h+2]
标志位:不影响
les指令
语法:les bx, es:[10F0h]
意义:和les类似,段地址放入es中,偏移地址放入操作的寄存器中。
相当于mov bx, word ptr es:[10F0h],mov es word ptr es:[10F0h+2]
即地址所指的内容,以两个4位16进制数的形式从高到低放入es bx中
标志位:不影响
标志寄存器传送指令
lahf指令
意义:把标志寄存器fl的低8位放入ah中
sahf指令
意义:把ah存入fl的低8位
pushf指令
意义:把fl压入堆栈,相当于
sub sp, 2 ; mov word ptr ss:[sp], fl
popf指令
意义:从堆栈弹出fl,相当于
mov fl, word ptr ss:[sp] ; add sp, 2
符号扩充指令
cbw指令
意义:convert byte to word
把al扩充为ax,若al最高位是1,扩充后ah是0FFh,若al最高位是0,则扩充后ah是00h
cwd指令
意义:convert word to dword
把ax扩充为dx ax,若ax最高位是1,则dx=0FFh,若ax最高位是0,则dx=00h
换码指令
xlat指令
意义:translate
ds:bx指向一个数组,对al进行赋值,xlat以后al被换成数组中对应的元素
比如ds:bx指向’0123456789ABCDEF’
mov al, 10
xlat
最后al=‘A’
算数指令
add指令
语法:add ax, bx
意义:ax=ax+bx
标志位:若非符号数相加产生进位,cf=1,则发生溢出(因为最高位发生了进位)
符号数负数+负数=正数,正数+正数=负数,正数-负数=负数,则发生溢出,of=1
注意点:一个操作数是寄存器,另一个是数字,寄存器,内存变量,或者一个是内存变量,另一个是数字
inc指令
语法:inc ax
意义:寄存器自加1
标志位:不影响标志位
adc指令
** 语法**:adc ax, bx
意义:带进位加,add with carry
ax=ax+bx+cf,用来计算一个加数放在两个寄存器中的情况
比如需要计算2F365h和5E024h的和
mov dx, 2h
mov ax, 0F365h ;dx:ax=2F365h
add ax, 0E024h
adc dx, 5
注意点:对操作数的要求和add指令一样
sub指令
语法:sub ax, bx
意义:ax=ax-bx
标志位:正数-负数=负数,of=1,负数-正数=正数(相当于负数+负数=正数)of=1
注意点:操作数要求与add相同
sbb指令
语法:sbb ax, bx
意义:sub with borrow 带位减法
ax=ax-bx-cf,和adc差不多,低位减完之后,高位相减需要用到sbb
dec指令
语法:dec ax
意义:ax自减1
标志位:不影响
注意点:操作数为寄存器或者内存变量
neg指令
语法:neg ax
意义:求相反数
标志位:非零数求补,cf=1,对0求补,cf=0
注意点:操作数为寄存器和内存变量
cmp指令
语法:cmp ax, bx
意义:两个数做差,根据标志位的变化判断大小,做差的结果被丢弃,后面一般跟跳转指令,可以比较寄存器,常数,内存变量
标志位:溢出of=1,负数sf=1,结果为0zf=1
(和sub一致)
跳转指令
非符号数跳转指令
指令 | 意义 | 判断标志位 |
---|---|---|
ja | 大于(above)则跳 | cf=0且zf=0 |
jae | 大于等于(above or equal)则跳 | cf=0 |
jb | 小于(below)则跳 | cf=1 |
je | 等于(below)则跳 | zf=1 |
符号数跳转指令
指令 | 意义 | 判断标志位 |
---|---|---|
jg | 大于(greater)则跳 | of=sf且zf=0 |
jge | 大于等于则跳 | of=sf |
jl | 小于(less)则跳 | of ≠ \ne =sf |
jle | 小于等于则跳 | of ≠ \ne =sf或zf=1 |
记忆方法:
大于和0是分别在于zf是不是1,所以先分正负,若是正在看是不是0.非符号数的正是减法不借位,cf=0,符号数的正是减法不溢出时结果为正,所以of=0,sf=0,of=sf
负数溢出说明真正的结果是正数,正数溢出说明真正的结果是负数,of=1则sf需要反一下才是正确的
白老师书中有错误,他在后续课程中说明了。
乘法指令
mul指令
语法:mul ax, mul al, mul es:[bx]
意义:可以跟8位,16位,32位的寄存器或者内存变量作为一个乘数
后跟8位操作数,另一个乘数是al,答案放在ax中,ax=albl
后跟16位操作数,另一个乘数是ax,答案放在dx:ax中,dx:ax=axbx
后跟32位操作数,另一个乘数是eax,答案放在edx:eax中,edx:eax=eax*ebx
imul指令
符号数乘法
div指令
语法:div bx,div bl, div es:[bx]
意义:可以跟8位,16位,32位寄存器或者内存变量作为一个乘数
后跟8位寄存器,被除数放在ax中,余数放在ah中,商放在al中,ax/bl=al…ah
后跟16位寄存器,被除数放在dx:ax中,余数放在dx中,商放在ax中,dx:ax/bx=ax…dx
后跟32位寄存器,被除数放在edx:eax中,余数放在edx中,商放在eax中
idiv指令
符号数除法
逻辑运算指令
and,or,xor,not(求反),test(比较两个操作数是否相同,影响zf)
以上操作数可以是寄存器,内存变量,常数。
除了内存变量和常数的组合,其他一定要寄存器参与。
位移指令
shl指令
语法:shl ax, cl
意义:逻辑左移,如果遇到大于1位,只能通过cl控制位移次数,右边补0。
标志位:移出的最后一位放入cf中
shr指令
语法:shr ax, cl
意义:左边补0,超过1只能用cl控制
标志位:移出的最后一位放在cf中
sal指令
算术左移,与逻辑左移完全相同
sar指令
算术右移,最高位是1则左边补1,是0则补0
rol指令
循环左移(rotate left),每一位往左移,同时最高位放在最低位上,cf是移完以后最低位。(每移动一次最高位都会被cf记录)
ror指令
循环右移,每一位往右,最低位移到最高位上,依次移动cl次,cf是移完以后最高位。(每移动一次最低位都会被cf记录)
rcl指令
带位循环左移
相当于把cf放在了最左边,然后一起参与循环左移
rcr指令
带位循环右移
相当于把cf放在了最右边,一起参与循环右移
字符串传送指令
movsb指令
语法:直接movsb
意义:把byte ptr ds:[si]传送到byte ptr es:[di]中,如果df=0,si,di加1,指向下一个字节,如果df=1,si,di减1,指向上一个字节
加上rep后,即rep movsb 重复cx次
movsw指令
与movsb 的区别是移动一个字,si.di变化的幅度是2
movs指令
movs byte ptr es:[di], byte ptr seg:[si]
和movsb差不多,但是允许移动任何位置的字符。
movs word ptr es:[di], word ptr seg:[si]
和movsw差不多
字符串比较指令
cmpsb指令
比较字节ds:[si]和es:[di],然后根据df的值移动di或者si
加上repe以后就会比较cx次
如果相等继续比较,不相等则不再比较,此时cx不一定为0,zf=0
repne cmpsb
比较时如果字符不等,则继续比较,直到相等,此时cx是剩余比较次数,zf=1