汇编语言-复习笔记

汇编复习笔记

以下描述中的内容都要掌握,但并不包含考试全部。

汇编是一门编程语言,结合代码掌握!


题目形式

第 1 题,改错

  • 大多是第 3 章中指令使用,可能比较隐晦,比如
    • 同时对两个内存操作 mov [di], [si]
    • 两个操作数类型不相同 sub ax, blmov cl, value[bx]
    • 用正确的方式实现 ADD [DI], [SI] 的本意。
    • 用正确的方式实现 MOV AX, CL 的本意。
    • push/pop 的不是16 位寄存器
    • 字节或字类型作为指令操作数
    • 段跨越前缀,源段 DS,目的段 ES(显式段赋值 或 默认段改变)
    • CS 不能用 MOV 指令改变 MOV CS, AX
    • SRC 和 DST 的字长不一致 MOV AH, 1234H
    • 不允许使用 AX、CX、DX 存放 EA, MOV AX, [CX] (能放地址的只有 5 个寄存器)
    • 必须是一个基址寄存器和一个变址寄存器的组合 MOV AX, [BX][BP]MOV AX, [SI][DI]
    • 对无操作数指令,不添加操作数。 STC AL,这是进位位置一指令
    • 对单操作数指令,操作数不能是立即数。IMUL 6
    • 内存操作数的属性应明确(立即数 MOV 到内存对属性敏感):
      MOV [BX], 0
      MOV byte ptr [bx], 0
      MOV word ptr [bx], 0
      MOV [bx], al
      MOV [bx], ax
      类似的 inc(或dec) word ptr rank[bx]
    • A、B、C、D、E、F开头的十六进制数前面加0,与H结尾的标识符区别。MOV al, ahMOV al, 0ah
    • 段寄存器无法直接赋值立即数 MOV DS, 1234h
    • 段寄存器无法直接赋值段寄存器 MOV DS, ES
    • 8086 中,移位指令的 CNT 只能是 1 或 CL SHL BL, 2
    • SEG、OFFSET 只能对符号地址操作 MOV AX, SEG [BX]MOV AX, OFFSET [SI]
    • MOV AX, [BX] 意味着 PA = 16d x (DS) + (BX)
      MOV AX, ES:[BX] 意味着 PA = 16d x (ES) + (BX)
      MOV AX, [BP] 意味着 PA = 16d x (SS) + (BP)

第 2 题,以 debug 形式

  • 改 ip 使得从第 3、4 条指令开始执行,内存偏移量地址,(ds)=?
  • 执行某行后 (AX) 或 FLAG 等寄存器的结果
    • NOT ax 不影响标志位,其他逻辑操作根据结果设置标志位,不过 CF=OF=0
  • u、t、g、r 等大概 4、5 种常用命令

第 3 题,读程序

  • 第 1 小题,程序不难但有点小技巧,比如累加程序(不是简单的1+2+3+...)。
    让你读懂程序后写结果。
  • 第 2 小题,输入一个数,显示一个数(比如进制转换、ASCII转换,复习PPT 115页)
    让你读懂程序后写结果。

第 4 题,子程序填空

  • 课本的例子程序、做实验自己写的程序,挖掉了某些语句,告诉子程序功能,填补语句
  • 应该是实验指导书前 2 章中自己做的程序。
  • 条件转移指令(有符号、无符号)必考

第 5 题,编程题

  • 比如排序题、人名排序、数据排序、电话号码簿排序
  • 中断 21h 的屏幕显示(字符、字符串)、读键盘(字符、字符串)
  • 如果都能写出来,就着重看汇编定义伪指令的正确与否

其他

累加、排序、插数、抽数

让你画出内存栈的变化结果

注意事项

  • 复习课 PPT 可能有针对 5、6、7 章类似的题

  • 第 3 章没什么示例、第 4 章作为大题考

  • 可能会掺杂 DS、ES 不同的问题

第一章

  • 进制转换

    • 比如 10-16 进制的转换,渗透考察
    • 注意读题给出的数是几进制
  • 数与字符的输入输出 —— ASCII 表

    • '0' = 48 = 30h
    • 'A' = 65 = 41h
    • 'a' = 97 = 61h
    • 回车符 = 13 = 0dh
    • 换行符 = 10 = 0ah,回车-换行符在 DOS 下要搭配使用
  • 空格符 = 20h

    • '$' = 24h
  • 补码运算

    • 老师:“出了相应的题,注意补码运算的性质、相对应的语句”

    • 猜测

      • 考察 $\begin{cases}[X+Y]_补 = [X]_补+[Y]_补 \ [X-Y]_补 = [X]_补+[-Y]_补\end{cases}$

      • 会以 第 2 题 debug 形式考,如

        1
        2
        3
        4
        5
        mov		al, 20h
        mov bl, 19h
        add al, bl

        打入 -t 指令,问寄存器结果、FLAG

第二章

  • 实模式寻址

    • 8086、8088 工作在 20 位地址下,单任务工作方式,独占系统所有资源。实模式下允许的最大寻址空间为 $2^{20} = 1\text{MB} $

    • 数据总线宽度是 16 位,地址总线宽度是 20 位,但寄存器是 16 位,所以划分每个段最大限长为 $2^{16} = 64\text{KB} $,理应需要增补高 4 位以形成 20 位地址,可以引入一个寄存器配合使用(段寄存器由来)

    • 但是,现在反过来,采用 小段 的方式划分段,即每 4 位(16 个字节)一个段,共 64K 个段。
      16 位段寄存器作高 16 位,段地址
      16 位寄存器作低 16 位,段内相对于段起始地址的偏移值,也叫有效地址 EA,这 16 位的高 12 位如果不为 0,就是 跨段
      二者相加,得到物理地址

    • 段是可以重叠的

    • 物理地址 = 段基址 x 16 + 段内偏址 = (段基址16位形式 << 1) + 段内偏址

    • 段寄存器与偏址寄存器的默认使用

  • 通用寄存器:数据/指针(变址) 寄存器的使用方式、默认搭配(隐含性质)

    • AX,accumulator,累加器
      BX,base,基址寄存器
      CX,count,计数器,移位操作的位数也可放到这里
      DX,data,数据寄存器
    • SP,stack pointer,堆栈指示器
      BP,base pointer,基址指示器
      SI,source index,源变址器
      DI,destination index,目的变址器
    • 只有 SP、BP、SI、DI、BX 可用于存放地址
    • 基址寄存器是:BX、BP
    • 变址寄存器是:SI、DI
    • 数据传送时,默认搭配 -> 第 3 章
    • 算术指令时,默认搭配 -> 第 3 章
  • FLAG 标志寄存器(或叫 PSW 程序状态字寄存器):

    • 条件码标志 —— 溢出 OF、符号 SF、零标志 ZF、进位 CF、辅助进位标志 AF、奇偶标志 PF

    • 控制码标志 —— 方向标志 DF(下图中DF是错的,应该为DF=0是增址方向、DF=1是减值方向)

    • 系统标志位 —— 中断标志 IF、陷阱标志 TF

    • 各个标志位的设置

    • debug 中会用到的标志位缩写

标志名字标志为 1标志为 0
溢出标志OF(Over flow flag)OV overflowNV no overflow
方向标志DF(Direction flag)DN downUP up
中断标志IF(Interrupt flag)EI enable interruptDI disable interrupt
符号标志SF(Sign flag)NG negativePL plus
零标志ZF(Zero flag)ZR zeroNZ no zero
辅助标志AF(Auxiliary carry flag)AC auxiliary carryNA no auxiliary
奇偶标志PF(Parity flag)PE parity evenPO parity odd
进位标志CF(Carry flag)CY carryNC no carry
  • 段寄存器:CS、DS、ES、SS
    • 代码段在最上面(一般不变动)
    • 堆栈段在最下面(向上生长)
  • 压栈,图形问法

    • 小端(低地址存低位字节),如下 12345678h

2.6 题

  • 解:,OF=0,SF=0,ZF=0,CF=0

第三章

40 分。基本语句记住,包括其注意事项

变址*比例因子,可能不考

堆栈指针,向上生长,压栈相当于指针减(SP的赋值)


  • 段跨越前缀,有三种情况不允许使用段跨越前缀:

    • 串处理指令的目的串必须用 ES
    • PUSH 指令的目的和 POP 指令的源必须用 SS 段
    • 指令必须存放在 CS 段中
  • ADD OPD, OPS 影响标志位

    • CF是否和的最高有效位向最高位的进位(按原码加法时是否有溢出)
      OF是否 源&目的操作数符号 与 结果符号相反
      ZF是否为零
      SF是否为负)
    • CF 位表示 无符号数 相加的溢出。
      OF 位表示 带符号数 相加的溢出。
  • SUB OPD, OPS 影响标志位

    • CF是否 被减数的最高有效位向高位的借位 (或者说 减法转换为加法运算时 无进位
      OF是否 两个操作数符号相反,而结果的符号与减数相同
      ZF是否为零
      SF是否为负)
    • CF 位表示 无符号数 减法的溢出。
      OF 位表示 带符号数 减法的溢出。
  • INC OPDDEC OPD不影响 CF,其他均影响

  • 乘法

    • 无符号乘法 MUL SRC
    • 有符号乘法 IMUL SRC
    • 字节乘法:AX ← (AL) * (OPS)
      字乘法:DX, AX ← (AX) * (OPS) 
      双字乘法:EDX, EAX ← (EAX) * (OPS)
  • 除法

    • 无符号除法 DIV SRC
    • 有符号除法 IDIV SRC
    • 字节除法:AH(余), AL(商) ← (AX) / (OPS)
      字除法:DX(余), AX(商) ← (DX, AX) / (OPS) 
      双字除法:EDX(余), EAX(商) ← (EDX, EAX) / (OPS)
  • BCD 码

    • 压缩的BCD码:用4位二进制数表示1位十进制数,例如:$(59){10} = (0101\ 1001){\text{BCD}}$
    • 非压缩的BCD码:用8位二进制数表示1位十进制数,例如:$(59){10} = (00000101\ 00001001){\text{BCD}}$
    • 数字的 ASCII 码是一种非压缩 BCD 码
    • BCD 码的加减法调整:
      即低四位范围属于 0-9,但运算过程中大于 9 且进位到高四位后其调整问题(加法举例)
  • 压缩的 BCD 码调整指令

    • 加法调整 DAA,decimal adjust on add 原理
      • 若 AF=1,或者 $\text{(AL)}_{0-3} > 9$,那么有进位,给低四位加上 06h = 0110b,即$\text{(AL)}\leftarrow \text{(AL)}+06h$,并且 AF=1
      • 若 CF=1,或者 $\text{(AL)}_{4-7} > 9$,那么高四位有进位,向 AH 进位了,要给高四位加上 06h,即$\text{(AL)}\leftarrow \text{(AL)}+60h$,并且 CF=1
    • 减法调整 DAS,decimal adjust on substract
      • 原理类似,只不过把上述对 AL 的加操作改为减
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
DATA SEGMENT
BCD1 DB 34H, 18H ; (1834)BCD
BCD2 DB 89H, 27H ; (2789)BCD
BCD3 DB 2 DUP (?)
DATA ENDS
实现:
(1) BCD3 ←BCD1 + BCD2; (4623)BCD
(2) BCD3 ←BCD1 -BCD2 ; (9045)BCD= -955

(1)
MOV AL, BCD1 ; (AL)=34H
ADD AL, BCD2 ; (AL)=34+89=BDH
DAA ; (AL)=BD+60+06=23H AF=CF=1
MOV BCD3, AL ; (BCD3)=23H
MOV AL, BCD1+1 ; (AL)=18H
ADC AL, BCD2+1 ; (AL)=18+27+1=40HAF=1 CF=0
DAA ; (AL)=40+06=46H
MOV BCD3+1, AL ; (BCD3+1)=46H
(2)
MOV AL, BCD1 ; (AL)=34H
SUB AL, BCD2 ; (AL)=34-89=ABH
DAS ; (AL)=AB-60-06=45H AF=CF=1
MOV BCD3, AL ; (BCD3)=45H
MOV AL, BCD1+1 ; (AL)=18H
SBB AL, BCD2+1 ; (AL)=18-27-1=F0H
DAS ; (AL)=F0-60=90H
MOV BCD3+1, AL ; (BCD3+1)=90H
  • 非压缩的 BCD 码调整指令

    • 大概率不会考到,所以不涉及了,并且原理可以自己推,主要把握一个要点:
      8 位二进制表示的非压缩 BCD 码中 高 4 位要常等于 0,低 4 位要属于 0-9 范围
    • 加法调整 AAA,ascii adjust on add 原理
    • 减法调整 AAS,ascii adjust on substract
  • 逻辑运算

  • 移位指令

    • 8086 中,移位指令的 CNT 只能是 1 或 CL
  • 移位指令:SF、ZF、PF 根据移位结果设置

    • 循环移位指令: 不影响 SF、ZF、PF、AF
指令全称
SHLshift left
SALarithmatic shift left
ROLrotate left
RCLrotate left with carry
  • REP MOVS

    • 首地址(末地址) → SI,注意是数据段
    • 目的串首地址(末地址)→ DI,注意是附加段
    • 串长度 → CX
    • 建立方向标志(CLD 使DF=0,STD 使DF=1)
  • 简单条件转移:

指令条件
JZ / JEZF=1
JNZ / JNEZF=0
JSSF=1
JNSSF=0
JOOF=1
JNOOF=0
JCCF=1
JNCCF=0
JP / JPEPF=1
JNP / JPOPF=0
  • 无符号数条件转移指令:
指令全称条件
JA / JNBEjump when aboveCF=0 且 ZF=0
JAE / JNBjump when above or equalCF=0 或 ZF=1
JB / JNAEjump when belowCF=1 且 ZF=0
JBE / JNAjump when below or equalCF=1 或 ZF=1
1
2
3
4
5
6
	CMP	AX, BX
JA L1
...
L1:
...
; 将 (AX), (BX) 当成无符号数,执行(AX)-(BX),若(AX)>(BX),则CF一定会为0,ZF=0,转移到L1处
  • 有符号数条件转移指令:
指令条件
JG / JNLESF=OF 且 ZF=0
JGE / JNLSF=OF 或 ZF=1
JL / JNGESF != OF 且 ZF=0
JLE / JNGSF != OF 或 ZF=1
  • 中断指令 INT Type 和 中断返回 IRET 实际执行的指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
INT:
pushf
IF <- 0
TF <- 0
AC <- 0
push cs
push ip ; 当然没有这条语句
(ip) <- (type*4)
(cs) <- (type*4+2)

iret:
(ip) <- pop ; ppt 上是这样,感觉有错误
(cs) <- pop
popf
  • 处理机控制指令 - 标志处理指令
指令全称作用
CLCclear carryCF <- 0
CMCcarry make changeCF <- $ \overline{\text{CF }}$
STCset carryCF <- 1
CLDclear directionDF <- 0
STDset directionDF <- 1
CLIclear interruptIF <- 0
STIset interruptIF <- 1
  • 其他指令
    • CBW,change byte to word,将 ax <- al

第四章

  • 伪指令定义
    • segment 定义
    • assume
      • ASSUME 语句只起指示作用,并无实际的操作,还要实际赋值段寄存器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
datasg1 segment
...
datasg1 ends
datasg2 segment
...
datasg2 ends
codesg segment
assume cs:codesg, ds:datasg1, es:datasg2
start:
mov ax, datasg1
mov ds, ax
mov ax, datasg2
mov ex, ax
...
codesg ends
end start
  • 退出 DOS
1
2
mov	ah, 4ch
int 21h
  • 超过 2 个字符的定义
  • $ 的使用
  • PTR 属性操作符
1
2
3
4
num db ?,?

mov ax, word ptr num
mov ax, dword ptr num
  • label 伪操作
    • 同一个地址可以赋予不同类型的 变量名
1
2
byte_array label byte   # 指向下一行变量定义的地址
word_array dw 50 dup(?)
  • 表达式赋值伪操作 EQU
1
2
3
CONSTANT   EQU  256
ALPHA EQU 7
BETA EQU ALPHA-2

第五章

课本例子 5.1 5.2 5.3 5.4 5.5 5.7 5.9,可能考读程序

  • 例:将 BX 中内容以十六进制显示出来

第六章

课本例子 6.9 6.10 6.11,通过堆栈传参

  • 例6.3 十进制到十六进制的转换(能默写)

第七、八章

  • 宏汇编,能看懂说出功能、会使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
宏定义:
multiply MACRO opr1,opr2,result
push dx
push ax
mov ax, opr1
imul opr2
mov result, ax
pop ax
pop dx
ENDM

# 宏指令名与指令助记符或伪操作名相同,宏指令的优先级最高
宏定义:
add MACRO opr1,opr2,result
...
ENDM
宏调用:
……
add xx,yy,zz
purge add;取消宏定义
……

等等 具体见 PDF 详细复习
  • 中断 21h 中输入输出,要求

    • 键盘输入 1 个字符 —— 1 号:

      • MOV AH, 1
        INT 21H
      • 功能:
        等待从键盘输入一个字符;
        将输入字符的ASCII 码 → AL;
        将该字符送显示器显示。
    • 显示输出 1 个字符 —— 2 号:

      • MOV AH, 2
        MOV DL, 带显示字符的 ASCII
        INT 21H
      • 功能:将 DL 中的字符送显示器显示
    • 显示输出字符串 —— 9 号:

      • LEA DX, 字符串首偏移地址
        MOV AH, 9
        INT 21H
      • 功能:从 DS:DX 所指向的单元开始,依次显示字符,直到遇到 ‘$‘ 为止。
      • 若字符串本身包含 ‘$‘ 就用 2 号调用循环输出吧
    • 键盘输入字符串 —— 10 号:

      • LEA DX, 缓冲区首偏移地址
        MOV AH, 10MOV AH, 0ah
        INT 21H
      • 功能:从 DS:DX 所指的输入缓冲区输入字符串并送显示器显示
  • in/out

    • 有一道 2、3 分的小题
    • 程序查询方式:CPU 利用 IN/OUT 指令直接在端口级上处理输入输出
    • CPU 通过不断查询外设状态,实现与外设的速度匹配。但工作效率低

图形显示、键盘、声音,中断不考

Debug 的使用

debug test.exe

  • DS=ES 指向当前最低的、可用的段地址(PSP的首字节);
  • CS:IPSS:BP 根据被调试程序确定,分别指向代码段和堆栈段;
  • BX : CX 为文件长度(双精度形成 32 位),其它通用寄存器和状态标志清 0

-r:register

  • 显示所有寄存器和标志位状态
    显示当前CS:IP指向的指令
  • 另一种用法 -R寄存器名显示并修改指定的寄存器,下一行输入修改值(16进制)
  • 自然可以修改 IP

-u [地址]

  • 反汇编命令,从指定地址开始反汇编 32 个字节的机器指令;
    省略地址时,则接着上一个 U 命令的最后一个单元开始;
    若第一次使用 U 命令省略地址,则从当前 CS:IP 开始

  • 另一种用法 -U100,从指定范围的单元 100 开始进行反汇编 32 个字节

  • 另一种用法 -U100L5,从指定范围的单元 100 开始进行反汇编 5h 个字节(注意是 16 进制)

g[=地址] [断点1 断点2 断点3 ... 断点10]

  • 从指定地址开始执行程序,直到程序结束 或 遇到 INT 3遇到定义的断点地址
    缺省时则从 CS:IP 指向的指令开始

-d [地址] [范围]:display

  • 从指定地址开始显示范围大小字节的内存区域
    地址缺省时,默认为ds:当前偏址
    范围缺省时,默认为 8行 x 16字节
    全缺省时,且第一次用,默认为 cs:0,后续则为在上次使用的基础上显示
  • 注意 DS 赋值后再显示

-t[=地址] [数值] :trace

  • 地址开始执行数值条指令
    地址缺省时,为 ip
    数值缺省时,为 1
  • 执行完后,显示寄存器内容、下一个待执行指令

-e 段:地址 [数据表]:edit

  • 从指定地址开始连续修改数据表内容
    如果数据表缺省,则进入交互模式,空格表示下一个单元,减号表示上一个单元,修改则主动输入,回车键表示结束并保存结果

-a[地址]:append

  • 从指定地址开始输入符号指令(写汇编,会覆盖原内容)
    如果地址缺省,则从当前 cs:ip 开始

Gift 2020.1.4

第 1 题 8x3=24分

(1)cmp al, bx
(2)add al, bx
(3)cmp [bx], 5
(4)mov [bx],[di]
(5)mov [cx],ax
(6)push al
(7)mov al, 300h
(8)mov bx, al

第 2 题 7空x2=14分

(1)下列程序段信息是使用DEBUG命令显示的结果,命令执行完后,AX,BX及IP的内容及标志位OF,CF的状态是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
C>DEBUG

-U 100 111

0F65:0100 BB0100 MOV BX,0001

0F65:0103 8A07 MOV AL,[BX]

0F65:0105 8A6701 MOV AH,[BX+01]

0F65:0108 38E0 CMP AL,AH

0F65:010A 7F03 JG 010F

0F65:010C 28C4 SUB AH,AL

0F65:010E CC INT 3

0F65:010F 28ED SUB AL,AH

0F65:0111 CC INT 3

-R

AX=0000 BX=0000 CX=0020 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=OF75 ES=OF65 SS=OF65 IP=0100 NV UP EI PL NZ NA PO NC

0F65:0100 BB0100 MOV BX,0001

-R IP

IP 0100

:0103

-G

AX=( ) BX=( ) CF=( ) OF=( ) IP=( )

(2)

1
2
3
4
5
6
7
-r ES 改为 0 
-d
.....内存信息....
.....内存信息....
...

问中断16h的偏址和段址

第 3 题
(1)一个计算斐波那契数列存到BUF数组中的程序
(2)一个读字符串然后倒序输出的程序

第 4 题

(1)补充BX输出十六进制程序
(2)人名排序即课本例子 6.11 中的 sort 部分

第 5 题 14分
(1)100h个16位补码数放在TABLE,求出现最多的数NUMB,和次数COUNT
(2)将BUF缓冲区中4位16进制数转换为ASCII存到MEM的4个字节中(例如 29a4,存到MEM是34h,41h,39h,32h 很奇怪),并要求输出


评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×