X86期末复习笔记
参考内容:往届复习笔记、上课ppt、上机例题和课本。
第一章 基础知识
数值及数制概念
数制:数制也称计数制,是用一组固定的符号和统一的规则来表示数值的方法。人们通常采用的数制有十进制、二进制、八进制和十六进制。任何一个数制都包含两个基本要素:基数和位权。
数值:计算机处理或运算时,利用数值进行运算。
输入输出及数值代码转换过程
二进制 — 十进制 — 十六进制
数值运算操作过程:码(输入) --> 值(计算) -->码(输出)
XOR BX, BX
MOV CX, 10
LOOP1: MOV AX, BX
MUL CX
MOV BX, DX
MOV AH, 1
INT 21H ;输入字符
XOR AL, 30H ;字符转化为值
ADD BL, AL
---
MOV CX, 0404H
LOOP16: ROL BX, CL ;循环左移,将最高为存到BL的低四位
MOV DL, BL
AND DL, 0FH
CMP DL, 9
JNA PRINT0
ADD AL, 'A'
JMP PRINT
PRINT0: OR AL, 30H
PRINT: MOV DL, AL
MOV AH, 2
INT 21H
DEC CH
JNZ LOOP16
---
MOV CX, 0
MOV AX, BX
MOV BX, 10
LOOP10: XOR DX, DX
DIV BX
PUSH DX
INC CX
CMP AX, 0
JZ PRINT
JMP LOOP10
PRINT: POP DX
OR DL, 30H
MOV AH, 2
INT 21H
DEC CX
JNZ PRINT
主要字符的ASCII码
字符 | Ascii码 |
---|---|
‘0’ – ‘9’ | 30H ~ 39H |
‘A’ – ‘Z’ | 41H ~ 5AH |
‘a’ – ‘z’ | 61H ~ 7AH |
’ ’ 空格 | 20H |
CR 回车 | 0DH |
LF 换行 | 0AH |
‘*’ | 2AH |
‘$’ | 24H |
汉字GB码以及Unicode都是双字节编码
第二章 IBM-PC 计算机组织
8086/8088 CPU组成
CPU包括运算器和控制器两部分。运算器负责执行所有的算术和逻辑运算,控制器则负责指令执行时的控制工作,包括把指令逐条从存储器中取出,经译码分析后发出取操作数、执行、存储运算结果等控制指令。
PC机的CPU最早是由Intel8086或Intel8088组成。8088是一个准16位的微处理器,即它的内部结构,如寄存器、寻址和执行机构,都是16位的,而外部的数据总线是8位的,因而它在一个总线周期内只能访问一个8位字节而不是一个16位的字。
Intel8088CPU内部共有14个16位寄存器,共有20根地址线,可直接寻址的空间为 2 20 = 1 M B 2^{20}=1MB 220=1MB。用于访问外部设备的I/O端口地址空间为64KB。
字长:16位
物理地址和逻辑地址运算
寻址范围:1MB(00000H–FFFFFH)基本单位为1字节
物理地址——20位;逻辑地址——段地址:偏移值;(多逻辑对一物理)
段地址*16D(10H)+ 偏移地址 = 物理地址
内存相关
内存中各种类型(字节、字、双字)数据的存放方式
字节:直接存放
字:低字节在前,高字节在后
双字:低字在前,高字在后
ex. 双字12345678H(32位二进制)存入内存单元1FFFFH处
内容 | 地址 |
---|---|
78 | 1FFFFH |
56 | 20000H |
34 | 20001H |
12 | 20002H |
内存图(含堆栈图)
寄存器
寄存器:(8个通用+4个段寄存器),PSW(IF,TF,SF,CF,ZF,DF,OF),IP (以及操作标志位的指令CLC/STC;CLD/STD——在第3章)
通用寄存器
通用寄存器 = 数据寄存器 + 指针寄存器 + 变址寄存器
数据寄存器
AX——累加器 BX——基址寄存器 CX——计数器 DX——数据寄存器
这四个寄存器可分做高八位和第八位,拆分成八个八位寄存器分别使用。
指针寄存器
SP——堆栈指针 BP——基址指针
变址寄存器
SI——原变址寄存器 DI——目的变址寄存器
能放到[]里的[BX,BP,SI,DI]
标志寄存器PSW
OF——溢出标志;DF——方向标志,0/1表示地址递增/减;SF——符号标志;
IF——中断标志;ZF——零标志,1表示结果为0;TF——陷阱标志;
CF——进位标志,1表示有进位/借位;PF——奇偶标志;AF——辅助进位标志;
进位标志CF(carry flag),当进行算术运算时,如果最高位产生了进位,则CF=1;否则CF=0。CF还用于移位指令,用于保存从最高位(左移时)或最低位(右移时)移出的代码。
符号标志SF(signflag),用于记录运算结果的符号,结果为负时SF=1;否则SF=0。由于运算结果的最高位就是符号位,所以SF与运算结果的最高位是一样的。
陷阱标志TF(trapflag),当TF=1时,在执行完一条指令后就会产生单步中断然后由单步中断处理程序把TF置为0。TF标志用于调试。
中断标志IF(interrupt flag),当IF=1时,允许响应可屏蔽中断,否则关闭中断。
溢出标志OF(overflow flag),在算术运算时,如果操作结果超过了机器用补码表示的范围时,OF-1;否则OF=0。
方向标志 DF(direction flag),DF用于控制串操作指令地址的增减。如果 DF=1,则每次串操作后使变址寄存器SI和DI减1(字节指令)或减2(字指令);如果DF=0,则每次串操作后使变址寄存器SI和DI加1(字节指令)或加2(字指令)。
CLC:CF=0 ;STC:CF=1
CLD:DX=0;STD:DF=1
段寄存器
CS——代码段;DS——数据段;SS——堆栈段;ES——附加段
指令指针寄存器
指令指针寄存器IP(instruction pointer)是一个专用的16位寄存器,它表示的是当前要执行的指令在代码段中的偏移地址。
SS:SP 为当前堆栈;CS:IP 为当前可执行点
堆栈
-
栈顶在堆栈外
-
PUSH OP == SP<–SP-2; SS:[SP]<–OP
-
POP OP == OP<–SS:[OP]; SP<–SP+2
第三章 寻址方式与指令系统
数据的6种寻址方式
寻址方式 | 说明 | 例子 | 常见错误 |
---|---|---|---|
立即寻址 | 指令所需的操作数直接包含在指令代码中 (常量或常数EQU) | VALUE EQU 512 MOV AL, 05H MOV AX, VALUE | 超出寄存器范围 (八位0-255) |
寄存器寻址 | 指令中所需的操作数是CPU的某个寄存器 | MOV AX, BX PUSHF | 使用段寄存器时数据通路不正确 不允许使用CS作为目的操作数 段寄存器不能给段寄存器赋值,不能被内存和立即数赋值 |
直接寻址 | 操作数的偏移地址直接在指令中指出 | MOV AX, [0200H] x DW ‘?’ MOV AX, x+1 | |
寄存器间接寻址 | 操作数的有效地址EA不是位于指令中,而是位于基址寄存器BX,BP或变址寄存器SI,DI中 | MOV AX, [BX] MOV BH, [BP] | 只有BX, BP, SI, DI可以间接寻址 缺省BP为SS段,其他为DS段 不能用BL/BH间接寻址 |
寄存器相对寻址 | 操作数的有效地址EA是一个基址寄存器或变址寄存器的内容和指令中指定的8位和16位位移量之和 | MOV AX, [SI+10H] MOV TABLE[DI+1], AL | |
基址变址 | 操作数的有效地址 EA 等于个基址寄存器(BX,BP)和一个变址寄存器(SI,DI)的内容之和 | MOV AX, [BX+SI+200] MOV ARRAY[BP+SI] | 果基址寄存器为BX,则缺省时段寄存器为DS;如果基址寄存器为BP,则缺省时段寄存器为SS 只有BXBP和SIDI可以 |
转移地址的4种寻址方式
寻址方式 | 说明 | 例子 |
---|---|---|
段内直接寻址 | 要转向(由JMP,条件转移CALL等)指令实际的有效地址是当前IP寄存器的内容和指令中指定的8位或16位位移量之和 | JMP LOOP CALL P1 |
段内间接寻址 | 转向的有效地址是一个寄存器或一个存储单元的内容。这个寄存器可以是 AX,BX,CX,DX,SI,DI,BP,SP | |
段间直接寻址 | 指令中给出了要转移至(由JMP和CALL 完成)的地址的代码段和偏移值内容,要转移至的标号或过程名必须具备FAR属性 | JMP FAR PTR P2 |
段间间接寻址 | 转移至的地址放入内存单元中,且是一个双字。 DWORD PTR后可以是除立即寻址和寄存器寻址方式外的任何一种数据寻址方式。 内存单元中的转移地址是一个双字,高位字在后,低位字在前。 转移后,低位字变成了IP,高位字变成了CS | JMP DWORD PTR [BX+INTERS] |
数据通路
掌握指令
MOV
源和目的必须类型匹配(8位对8位,16位对16位)。
目的操作数不能为立即数。
源和目的操作数不能同时为内存操作数(串指令除外)。
源和目的操作数不能同时为段寄存器。
不影响标志寄存器
类型转换
仅凭符号名或变量名很难准确地知道内存操作数的类型。
通过 BYTE PTR,WORD PTR,DWORD PTR三个操作符,可以明确地指定内存操作数的类型,或进行强制类型转换:
MOV BYTE PTR x, AL
MOV WORD PTR [DI], AX
XCHG
其作用是两个操作数的内容互换(OPR1<–>OPR2)。不允许任何一个操作数使用立即数。不影响标志寄存器
POP/PUSH/POPF/PUSHF
堆栈的存取只能以字为单位,不允许以字节为操作数。PUSH指令可以使用CS寄存器,但POP指令不可以使用CS寄存器。除此以外,可以使用除立即数以外的任何数据寻址方式。堆栈操作不影响标志寄存器。
地址传送指令LEA/LDS/LES
指令 | 格式 | 说明 |
---|---|---|
LEA | LEA reg, src | 将源操作数src的偏移地址送入reg中 |
LDS | LDS reg, src | 将src中的双字内容依次送入reg及DS中 |
LES | LES reg, src | 将src中的双字内容依次送入reg及ES中 |
指令中的reg不能是段寄存器。LEA 指令获取的是src的偏移地址,而不是它的内容。LDS是将src 处的双字取来将低字(在前面)送入src,将高字(在后面)送入DS寄存器。src处所保存的双字一般都是某个程序或变量的逻辑地址(seg:offset)。LES的作用与LDS类似,只是使用的是ES寄存器。
加法和减法指令
立即数当最高位为A~F时;要再补一个0,以免与变量名相混淆
利用ADC(带进位加)或SBB(带借位减)可以实现32位的加法或减法,注意ADD ADC|| SUB SBB必须挨着,以免CF被破坏
CMP与NEG指令
CMP(比较)和NEG(求补)指令是两条特殊的指令。NEG指令用于求操作数的补码,CMP指令则比较两个数的大小,它的本质是用目的操作数减源操作数,但结果不送回到目的操作数。因为做了减法,所以会产生标志位,而这些标志位正是进行条件转移时的“条件”
MUL指令和CBW指令
字节操作数–8位x8位,AX-AL*src
字操作数–16位x16位,DX:AX←AX*src。其中,DX:AX为32位乘积,DX为高16位,AX为低16位
CBW指令无参数,它的作用是将AL的符号扩展至AH。如果AL的最高位为0,则AH=00;如果AL的最高位为1,则AH=0FFH。
除法指令DIV
当src为字节操作数时,16位被除数在AX中,8位src为除数,结果为8位的商在AL中,8位余数在AH中。
当src为字操作数时,32位被除数位于DX:AX中(DX为高16位,AX为低16位),16位src为除数,结果为16位的商在AX中,16位余数在DX中。
它的源操作数(除数)是通用寄存器或任何一种内存寻址方式确定的操作数,特别是它不能为立即数。
必须用32位数除以16位数,16位数除以8位数,不能是16位数除以16位数。
对无符号数除法,如果被除数为16位,应先将它放入AX中,然后将DX清零。
逻辑指令
逻辑运算指令
AND(逻辑“与”)、OR(逻辑“或”)、XOR(逻辑异或”)和 NOT(逻辑“非”)
移位指令
逻辑左移SHL;算术左移SAL
逻辑右移SHR;算术右移SAR
循环左移ROL;循环右移ROR
带进位循环左移RCL;带进位循环右移RCR
控制转移指令
无条件转移指令JMP
条件转移指令
指令 | 说明 |
---|---|
JZ/JE | 如果ZF=1则转移至标号处 |
JNZ/JNE | 如果ZF=0则转移至标号处 |
JC | 如果CF=1则转移至标号处 |
JNC | 如果CF=0则转移至标号处 |
JA/JB/JE/JNA/JNB/JNE/JNBE/JNAE | 两个无符号数比较后结果 |
循环指令
LOOP 标号 --> CX=CX-1; CX!=0转移,反之顺序向下运行
过程调用和返回指令
过程:
CALL指令的执行:
返回指令:
处理器控制命令
处理器控制命令没有参数,它们用于CPU的内务操作。
代码实践
AH | 含义 |
---|---|
1 | 键盘输入并回显 |
2 | 显示输出, DL=输出字符 |
9 | 显示字符串,DS:DX=串地址,'$'结束字符串 |
A | 键盘输入到缓冲区,DS:DX=缓冲区首地址 |
4CH | 带返回码结束,AL=返回码0. |
复习不完了,默写代码默写不了一点。
重点例题和图表
易错点
-
mul 和 div 的操作数不能为立即数,操作位数取决于其后操作数的位数,来自动处理
-
div的被除数是16位时,需要将dx清零
-
除以10时,需要用DX:AX / 10。因为65535除以10为6553,大于255,商会溢出(商在AX,余数在DX)。
-
位移指令的dst不能是立即数,count只能是1或者CL
-
用AH=0AH输入字符串时,会从偏移地址第三个字节开始存储字符串(STR+2)