本文是上学期学习汇编语言时候的课堂笔记。
分类索引(单击命令直接索引)
分类 | 命令 |
---|---|
符号数相关 | JG 、JL 、IMUL |
通用数据传送指令 | MOV 、POP 、PUSH 、XCHG 、IN 、OUT |
地址传送指令 | LEA 、LDS 、LES 、PUSHF 、POPF |
转换指令 | CBW 、CWD 、XLAT |
加减乘除 | ADD 、INC 、ADC 、SUB 、DEC 、NEG 、MUL 、DIV |
逻辑运算 | AND 、OR 、XOR 、NOT 、TEST |
移位指令 | SHL 、SHR 、SAL 、SAR 、ROL 、ROR 、RCL 、RCR |
字符串操作 | MOV 、CMPSB 、SCASB 、STOSB 、LODSB |
控制转移指令 | JMP 、LOOP 、CALL 、RETN 、RETF |
符号数相关
jg/jl大小比较
jg 符号数大于
jl 符号数小于
跳转依据:
符号 | 依据 |
---|---|
a < b | SF!=OF |
a==b | ZF=0 |
a > b | SF=OF且ZF=0 |
1 | ah=0FFh, bh=1 |
imul 符号数乘法
- imul eax
只寄存器
, ebx寄存器或变量
, 1234h只常数
eax = ebx * 1234h - imul eax, ebx
eax自乘ebx
通用数据传送指令
MOV 指令
1 | [√] mov byte ptr ds:[bx], ah |
DS
/CS
/IP
不能被mov改变
mov 的变体
movzx
: move by zero extentionmovsx
: move by sign extention[rep] movsb
; 以字节为单位移动CX个字符
DS : SI 指向源字符串
ES : DI 指向目标字符串
若 DF=0 即正方向则SI++,DI++,否则反之。
POP / PUSH 指令
- 不能对8位值进行push/pop:
1 | [×] push ah |
XCHG 指令
(略)
IN / OUT 指令
基本格式:1
in al, 21h
从21h号端口读取一个字节存放到AL中
- 端口地址>=100h,必须存放到DX
- 端口地址的范围是:[0000h, 0FFFFh],共65536个端口。
地址传送指令
LEA `取变量的偏移地址`
1 | lea eax, [ebp-64] |
EAX = EBP-64
- lea dx, ds:[1000h] ; DX=1000h
- 设BX=1000h, SI=2
lea ax, ds:[bx+si+3]; AX=bx+si+3=1005h
LDS `把远指针装到DS:DEST`
1 | lds dest, src |
把 src
指向的地址,高位存放在DS
中,低位存放在dest
中。
16位时,
比如当前DS=1000H, BX=0100H.
当前内存:
1000:0100 01
1000:0101 02
1000:0102 03
1000:0103 04
而有一条指令:LDS BX,[BX]
[BX]指向1000:0100,执行后BX存低位的内容,也就是BX=0201H,
而DS则存高位的内容,也就是[BX+2]的内容,DS=0403H
LES `把远指针装到ES:DEST`
1 | les dest, src |
PUSHF,POPF `标志寄存器传送指令`
(把FL压入/弹出ax)1
2
3
4
5pushf
pop ax ; AX=FL
or ax, 1; 第0位变1,其它位不变
push ax
popf ; FL=AX
转换指令
CBW,CWD `符号扩充指令`
CBW: convert byte to word
CWD: convert word to double word
CDQ: convert double word to quadruple word(32位扩充为64位)
1 | mov al, 7Fh |
1 | mov al, 0F9h |
1 | mov ax, 8000h |
1 | mov eax, 0FFFFFFFFh |
movzx
: move by zero extentionmovsx
: move by sign extention
XLAT `换码指令`
1 | ; 设 char t[]="0123456789ABCDEF"; |
加减乘除
加
指令 | 用法 |
---|---|
add | |
inc | 不影响CF位 |
adc | 带进位加法。当进行32位以上运算时,要求低位字节相加,而高位字节再相加时就要考虑低位相加的进位,即CF |
减
指令 | 用法 |
---|---|
sub | |
dec | 自减 |
neg | 求相反数 |
乘 `非符号`
1 | mul src |
src 不能是立即数,寄存器和地址均可
src字节数 | 操作对象 | 结果存放 |
---|---|---|
8字节 | al | ax |
16字节 | ax | dx : ax |
32字节 | eax | edx : eax |
即 AX = AL * src
除 `非符号`
1 | div op |
op字节数 | 操作对象 | 结果存放 |
---|---|---|
8字节 | ax | al(整除);ah(余数) |
16字节 | dx : ax | ax(整除);dx(余数) |
32字节 | edx : eax | eax(整除);edx(余数) |
语句比较
test
/and
(cmp
/sub
)
运算结果不影响操作数,只影响标志位。
影响标志: C,O,P,Z,S(其中C与O两个标志会被设为0)neg
/not
neg
求相反数,not
逐位求反inc
/add
是否影响flagjc
与jb
指令完全等价。jz
与je
指令完全等价。
比较方法
- 非符号数:CF / ZF
- 符号数:SF / OF / ZF
OF=1 即结果溢出(有错),否定SF得到的符号结果
逻辑运算和移位
逻辑运算指令
AND
,OR
,XOR
,NOT
,TEST
移位指令
SHL
,SHR
,SAL
,SAR
,ROL
,ROR
,RCL
,RCR
1
shl ah, 1
**单向**
符号 | 含义 | 作用 |
---|---|---|
SHL | 逻辑左移 | 低位补0, 高位进CF |
SHR | 逻辑右移 | 低位进CF, 高位补0 |
SAL | 算术左移 | (同SHL) |
SAR | 算术右移 | 每位右移, 低位进CF, 高位不变 |
它们的结果影响 OF、SF、ZF、PF、CF
**循环**
符号 | 含义 | 作用 |
---|---|---|
ROL | 循环左移 | 高位到低位并送CF |
ROR | 循环右移 | 低位到高位并送CF |
RCL | 带进位循环左移 | 进位值(原CF)到低位, 高位进CF |
RCR | 带进位循环右移 | 进位值(原CF)到高位, 低位进CF |
它们的结果影响 OF、CF
8086中,当次数>=2时,移位次数应先赋值给 cl
字符串操作
MOVSB `字符串传送`
1 | [rep] movsb |
以字节为单位,从 DS:SI 到 ES:DI 移动CX个字符
- DF控制方向。若DF=0即正方向则SI++,DI++。
CMPSB `字符串比较`
1 | [repe | repne] cmpsb |
若本次比较 相等
/ 不等
则继续比较下一个
SCASB `字符串查找`
1 | [repe | repne] scasb |
设ES:DI → 以’\0’结束的字符串,要求该字符串长度1
2
3
4
5
6
7
8
9mov ax, 1000h
mov es, ax
mov di, 1080h ; ES:DI → "ABC..."
mov cx, 0FFFFh ; ES:DI → "ABC",0,[]...
mov al, 0 ; AL=待查找的字符
cld
repne scasb ; 循环结束时,DI=1088h, CX=FFFF-8
inc cx
not cx ; CX=FFFF-CX=字符串长度(不含0)
STOSB `存入字符串`
1 | [repe] stosb |
stosb把AL的值保存到ES:DI所指向的内存单元中
- 当DF==0时DI++,当DF==1时DI—
设要把从地址1000:10A0开始共100h个字节内存单元全部填01
2
3
4
5
6
7mov ax, 1000h
mov es, ax; ES=1000h
mov di, 10A0h
mov cx, 100h
cld
xor al, al
rep stosb
LODSB `从字符串取字节或字`
1 | lodsb |
AL = DS : [SI], SI++
控制转移指令
JMP
1 | [√] jmp 0108h |
LOOP
CX-1
CALL,RETN,RETF `子程序调用与返回`
retn表示近返回,可简写成ret;
retf表示远返回。
call既可以表示近调用,也可以表示远调用
retn [count] ; count
多出步骤:SP = SP + count
堆栈传递1
2
3
4
5
6
7
8
9
10
11
12f:
push bp
mov bp, sp
mov ax, [bp+4]; 从堆栈中取得参数
add ax, ax
pop bp
ret
main:
mov ax, 3
push ax; 参数压入到堆栈
call f
add sp, 2
C语言函数调用y=f(2,3)求两数之和转化成汇编语言1
2
3
4
5
6
7
8
9
10
11
12
13
14
15f:
push bp;(4)
mov bp, sp
mov ax, [bp+4]
add ax, [bp+6]
pop bp; (5)
ret; (6)
main:
mov ax, 3
push ax; (1)
mov ax, 2
push ax; (2)
call f; (3)
here:
add sp, 4;(7)
上述程序运行过程中的堆栈布局如下:
ss:1FF8 old bp <- bp (4)
ss:1FFA here <- (3)(5)
ss:1FFC 02 <- (2)(6)
ss:1FFE 03 <- (1)
ss:2000 ?? <- (7)
cx/dx可以随便用
ax一般用作返回值