X86知识点
一、基础知识
数值及数制概念
数制:二进制(计算机处理、运算)、十六进制(人看待机器中的二进制的数制)、十进制(人进行计算的数制)等
数值:计算机处理或运算时,利用数值进行运算。
例:100H-2H = FEH 记住10H-1H = FH
输入输出及数值代码转换过程(大题必考)3步
(1)输入’1’‘2’
(2)ASCII码转换成值
(3)十进制至二进制
(4)输入‘1’‘2’
(5)ASCII码转换成值
(6)十进制至二进制
(7)做乘法
(8)输出
STACK SEGMENT PARA STACK
DW 100H DUP(?)
STACK ENDS
DATA SEGMENT PARA
X DW ?
Y DW ?
Z DW ?
INPUT_S DB "Please input: ", 0dh, 0ah, '$'
OUTPUT_S DB "Multi outcome is: ", 0dh, 0ah, '$'
NEW_LINE DB 0DH, 0AH, '$'
DATA ENDS
CODE SEGMENT PARA
ASSUME CS:CODE, SS:STACK, DS:DATA
MAIN PROC FAR
MOV AX, DATA
MOV DS, AX
MOV DX, OFFSET INPUT_S
MOV AH, 9
INT 21H
CALL GET_NUM
MOV X, AX
MOV DX, OFFSET INPUT_S
MOV AH, 9
INT 21H
CALL GET_NUM
MOV Y, AX
CALL MULTI
CALL OUTPUT_HEX
EXIT: MOV AX, 4C00H
INT 21H
MAIN ENDP
GET_NUM PROC NEAR
PUSH BX
PUSH CX
PUSH DX
PUSH SI
XOR SI, SI
MOV BX, 10
GN_LP1: MOV AH, 1
INT 21H
CMP AL, 0DH
JZ GN_END
CMP AL, 30H
JB GN_CONTINUE
CMP AL, 39H
JA GN_CONTINUE
SUB AL, 30H ;【注】输入满足条件后要减去30h
XOR AH, AH
PUSH AX
MOV AX, SI
MUL BX
MOV SI, AX
POP AX
ADD SI, AX
GN_CONTINUE:JMP GN_LP1
GN_END: MOV AX, SI ;【注】用AX传递参数回去,我错就错在没有把得到的值存到内存的相应位置!!!
POP SI
POP DX
POP CX
POP BX
RET
GET_NUM ENDP
MULTI PROC NEAR
PUSH AX
MOV AX, X
MUL Y
MOV Z, AX
POP AX
RET
MULTI ENDP
OUTPUT_HEX PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX, 4
MOV BX, Z
OH_LP1: PUSH CX
MOV CL, 4
ROL BX, CL
MOV DX, 000FH
AND DL, BL
ADD DL, 30H
CMP DL, 39H
JBE OH_DIS
ADD DL, 'A'-'9'-1
OH_DIS: MOV AH, 2
INT 21H
POP CX
LOOP OH_LP1
POP DX
POP CX
POP BX
POP AX
RET
OUTPUT_HEX ENDP
CODE ENDS
END MAIN
汉字GB码以及Unicode都是双字节编码
回车0dh 换行
8086/8088 CPU组成
PC机的三大部分: CPU(8086 16位,80386 32位)、存储器、IO
8086/8088 CPU三部分: ALU、控制逻辑、寄存器组
字长:16位 地址:20位 寻址能力:1MB(00000h-fffffh)
寄存器
8个通用寄存器:AX,BX,CX,DX,SI,DI,BP,SP 能放到[]里的[BX,BP,SI,DI]
SI(源变址) DI(目的变址):变址寄存器 SP*(堆栈指针)* BP*(基址指针)*: 指针寄存器
4个段寄存器:DS,CS,SS,ES
标志寄存器PSW:IF中断 TF陷阱 SF符号 CF进位 ZF0 DF方向 OF溢出 AF辅助进位 PF奇偶
CLC CF=0 STC CF = 1
ACDIOPTSZ
原码:1010 1001 补码:1101 0111.
从最低位开始至找到的第一个1均不变,符号位不变,这之间的各位“求反”(0变1;1变0)。
指令 | 对PSW影响 |
---|---|
ADD/SUB | CF/OF/ZF/SF/AF/PF |
NEG | 用0减,CF=1 |
INC/DEC | 不影响CF,OF/ZF/SF/AF/PF |
AND/OR/XOR/TEST | 将进位和溢出都清零了。CF=0,OF=0 SF/PF/ZF |
NOT | 不改变标志位 |
SHL/SHR/SAL/SAR | 移入CF,CF/OF/ZF/SF/AF/PF |
RCL/RCR/ROL/ROR(区别在于一圈循环多了一个CF n->n+1) | 不修改SF/ZF/AF/PF |
MUL/DIV | 高位有值就OF、CF=1 |
上面表格重点要记住:位操作AND/OR/XOR CF=0 DF=0 OF=0
INC DEC不影响CF
物理地址和逻辑地址运算
将1MB的地址分段、每段最大64KB
物理地址:20位二进制表示
逻辑地址:段地址+偏移值
同一物理地址可能有多个逻辑地址的组合
堆栈
栈顶指针不能存放
PUSH OP: SP=SP-2, SS:[SP]=OP
POP OP: OP=SS:[SP], SP=SP+2
二、寻址方式
数据的6种寻址方式、转移地址的4种寻址方式
BP,SP,BX,SI,DI的默认寻址段(SS还是DS):BP\SP:SS BX\SI\DI:DS
**字符串:**DS:[SI]->ES:[DI]
重点指令
LEA(OFFSET),LDS,LES;——习题及例题,课堂练习
JMP,CALL,INT n/IRET,RET/RETF/RET 2n;
LOOP; ——练习及例题
ADD,ADC,SUB,SBB应用;
MUL,DIV(8位/16位)应用;
三、X86指令(判断题)
段超越
SS:[BP] 不能出现SS:[SP]
CS:[IP] 不对,不能这么寻址,转移指令可以访问
一、数据传送指令
1.MOV体操 a不改变标志位!!! b数据类型要一致
不存在数据通路
1.内存->内存
MOV X, WORD PTR [BX]
MOV DWORD PTR [SI], Y
2.立即数->段寄存器
MOV DS, 1823H
3.段寄存器->段寄存器
MOV ES, DS
立即数-内存谁也没有给出大小
MOV [BX], 10 X
2.XCHG体操
1.不允许任何一个是立即数。因此能处理的对象没有立即数
2.只能处理rr mr rm显然无mm
3.不能段寄存器
综上xchg比mov能力弱,只在r与m起作用
3.LEA/LDS/LES
dst不能为段寄存器
例题:内存操作数之间的传送
1.内存图
2.不同大小的内存块要互相传数据
二、算术运算指令 显然加减乘除运算必考!!!
1.ADD/SUB
注意ADD ADC|| SUB SBB必须挨着,以免CF被破坏
2.MUL/DIV
不能为立即数,甚至可以是内存
MUL BYTE PTR [SI]
MUL X1
这些都行,就是不能MUL 10
三、逻辑运算指令
1.AND/OR/XOR/NOT
OR AL, 30H
AND AL, 0FH
2.移位指令(必考)xgx多次提到怎么画
一定是一个双字在移位,看清楚是移动谁
SHL紧跟RCL
四、控制转移指令
1.loop/JCXZ
当CX=0,执行ffffh次
执行顺序:CX <- CX -1 ;判断CX是否为0;不为0跳转到标号
JCXZ:当CX = 0时跳转,不执行CX变化的操作。常见于:DEC CX JCXZ L1
2.JA/JB/JE
例:Z=|X-Y|
MOV AX, X
CMP AX, Y
JAE CONTINUE
XCHG AX, Y
CONTINUE:
SUB AX, Y
MOV WORD PTR Z, AX
3.JMP
段内直接寻址 JMP SHORT L1 没有ptr, JMP NEAR PTR L1
段内间接寻址 JMP WORD PTR AX/MEM
段间直接寻址 JMP FAR PTR L1
段间间接寻址 JMP DWORD PTR L1
考点:指令的寻址方式和执行过程
例:
JMP FAR PTR L1 段间直接寻址。IP<-l1的偏移地址, CS<-l1的段地址。标号属性为FAR
JMP WORD PTR BX X 寄存器不存在ptr,ptr是指针仅针对内存单元
JMP WORD PTR [BX] 段内间接寻址。IP<-DS:[BX] 同JMP [BX]
JMP DWORD PTR [BX] 段间间接寻址。IP<-DS:[BX], CS<- DS:[BX+2]
JMP DWORD PTR add1 段间间接寻址。IP <- [add1], CS<- [add1+2]
4.CALL
CALL BX 段内间接寻址。sp <- sp -2 ss:[sp] <-下一条指令的地址 IP=BX
CALL [BX] 段内间接寻址。sp <- sp -2 ss:[sp]<-下一条指令的地址 IP<- DS:[BX]
CALL DWORD PTR [BX] 段间间接寻址。sp <- sp -2 ss:[sp]<-下一条指令的短地址 sp<-sp-2 ss:[sp] <-下一条指令的偏移地址 IP <- DS:[BX] CS <- DS:[BX+2]
5.RET
段间返回编译成RETF
RET exp IP<-SS:[SP] SP=SP+2 CS<-SS:[SP] SP=SP+2 SP=SP+EXP(偶数)
标号与过程名
定义了代码段内的偏移值
画堆栈图考
改标记寄存器指令(必考)
CLC STC CLD STD CLI STI NOP
例:令IP为0的指令CLI
令CF置位的指令STD CLD时是递增的,DF置位时是递减的(逆序遍历)
置位就是为1,复位就是清零
五、字符串处理
字符串操作:复制、比较、查找、插入、删除、组合
CLD STD 超重要!!!!
字符串指令
取串指令:LODSB/LODSW
存串指令:STOSB/STOSW
串传送指令:MOVSB/MOVSW
串比较:CMPSB/CMPSW
串扫描:SCASB/SCASW
重复前缀:REP 必须位于传操作指令之前
条件重复前缀指令:REPE, REPZ CX$\ne$0且ZF=1时执行串指令
传操作指令的应用(简答题考查)
例:用REP MOVSB将BUFF1传送到BUFF2,长度都为LEN
PUSH ES
PUSH DS
POP ES
MOV SI, OFFSET BUFF1
MOV DI, OFFSET BUFF2
MOV CX, LEN
CLD
REP MOVSB
POP ES ;保持堆栈平衡!!!莫失莫忘
例:REP STOSB将LEN BUFF清0
PUSH ES
PUSH DS
POP ES
MOV DI, OFFSET BUFF
MOV CX, LEN
CLD
MOV AL, 0
REP STOSB
POP ES
例:长度为LEN的缓冲区BUFF1小写字母变大写
PUSH ES
PUSH DS
POP ES
MOV SI, OFFSET BUFF1
MOV DI, OFFSET BUFF1
MOV CX, LEN
CLD
LP1: LODSB
CMP AL, 61H ;'a'也可以的
JB CONTINUE
CMP AL, 7AH
JA CONTINUE
SUB AL, 20H
STOSB
CONTINUE:
LOOP LP1
POP ES ;!!!!!!!!!!!!!!!!!!!!!!!!!!!莫失莫忘
例:比较STRING1与STRING2按字典序排序的大小,长度为LEN
PUSH ES
PUSH DS
POP ES
MOV SI, STRING1
MOV DI, STRING2
MOV CX, LEN
CLD
REPZ CMPSB ;CMPSB 当ZF=1说明比较的结果相等,如果最后都是相等的,那说明两个就是相等。所以使用了有条件重复前缀,REPZ当相等时比较下一个。出来以后就可以看CF到底谁大谁小
JA LAB1
JB LAB2
...
POP ES
还可以根据CX的值看比较了多少次
例:长度为LEN的STRING1串是否有字母A
PUSH ES
PUSH DS
POP ES
MOV DI, OFFSET STRING1
MOV CX, LEN
CLD
MOV AL, 'A'
REPNZ SCASB ;没找到就一直循环,如果时因为ZF=1停下来的,说明找到了;如果是因为CX=0,那就是没找到
JZ FOUND
...
POP ES
上方是只会在简答题里出现的套路串指令使用,LEN一般是不会给的
灵活串操作(大题必考且分值最高)
查找+删除
例:从缓冲区找到0DH,0AH并删除
STACK SEGMENT PARA STACK
DW 100H DUP(?)
STACK ENDS
DATA SEGMENT PARA
BUFF DB 0DH, 0AH
DB "Test line2:1234", 0DH, 0AH
DB "Test line3:5678", 0DH, 0AH
DB 0DH, 0AH
DB '$'
BUFF_LEN EQU $ - BUFF
BUFF_END DW $
DATA ENDS
CODE SEGMENT PARA
ASSUME CS:CODE, DS:DATA, SS:STACK
MAIN PROC NEAR
MOV AX, DATA
MOV DS, AX
MOV ES, AX ;竟然卡在这里了!!!!忘了搞ES了
MOV DX, OFFSET BUFF
MOV AH, 9
INT 21H
MOV DI, OFFSET BUFF
LP1: MOV BX, BUFF_END
CMP DI, BX
JAE LP_END
CMP WORD PTR [DI], 0A0DH ;【注】作为一个字取出来以后是反的
JNZ CONTINUE
PUSH DI
MOV SI, DI
ADD SI, 2
MOV CX, BUFF_END
SUB CX, DI
CLD
LP2: LODSB
STOSB
LOOP LP2
;REP MOVSB
SUB BUFF_END, 2
POP DI
CONTINUE: INC DI
JMP LP1
LP_END: MOV AH, 9
MOV DX, OFFSET BUFF
INT 21H
EXIT: MOV AX, 4C00H
INT 21H
MAIN ENDP
CODE ENDS
END MAIN
- ##### 查找+插入(会出现覆盖了STD)
例:查找0AH,补成0DH, 0AH
六、堆栈传递参数
[BP+4] [BP+6]
POP BP
RET 4 ;因为压入了
原来我这里一直记错了(可怕ヽ(*。>Д<)o゜)
重点代码默写
字符串操作
-
1.查找+插入
-
2.查找+删除
1.插入和删除改变了字符串的总长度,所以在loop的时候要ADD BUFF_END, 2或 DEC BUFF_END
2.存在缓冲区是1234h,取一个字的时候是3412h。同理,我想要在缓冲区变成1234,其实存入一个字的顺序是3412h
3.考察点:ES,DS,DI,SI,CX,CLD/STD,AL
- 3.字符串排序+插入
STACK SEGMENT PARA STACK
DW 100H DUP(?)
STACK ENDS
DATA SEGMENT PARA
BUFF DB 'ZhangJiayuan','$'
BUFF_LEN EQU $ - BUFF
BUFF_END DW $
NEW_LINE DB 0DH, 0AH, '$'
DATA ENDS
CODE SEGMENT PARA
ASSUME CS:CODE, DS:DATA, SS:STACK
MAIN PROC FAR
MOV AX, DATA
MOV DS, AX
MOV ES, AX
MOV DX, OFFSET BUFF
MOV AH, 9
INT 21H
MOV DX, OFFSET NEW_LINE ;new_line
MOV AH, 9
INT 21H
CALL SORT
CALL INSERT
MOV DX, OFFSET BUFF
MOV AH, 9
INT 21H
EXIT: MOV AX, 4C00H
INT 21H
MAIN ENDP
SORT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH SI
MOV CX, BUFF_LEN
DEC CX
DEC CX ;因为最后一个是字符串的终止符,不能把它也一起排序了
SORT_LP1: PUSH CX
MOV SI, OFFSET BUFF
MOV BX, 1
SORT_LP2: MOV AL, [SI] ;
CMP AL, [SI+1]
JBE SORT_CON
XCHG AL, [SI+1]
MOV BYTE PTR [SI], AL
MOV BX, 0
SORT_CON: INC SI
LOOP SORT_LP2
POP CX
CMP BX, 1
JZ SORT_END
LOOP SORT_LP1
SORT_END: POP SI
POP CX
POP BX
POP AX
RET
SORT ENDP
INSERT PROC NEAR ;STD
PUSH AX
PUSH CX
PUSH BX
PUSH SI
PUSH DI
MOV BX, 1
MOV DI, OFFSET BUFF
INSERT_LP1: CMP DI, BUFF_END
JAE INSERT_END
CMP BYTE PTR [DI], 'C'
JBE INSERT_CON
MOV BX, 0
PUSH DI
MOV CX, BUFF_END
SUB CX, DI
MOV DI, BUFF_END
MOV SI, DI
DEC SI
STD
REP MOVSB
POP DI
MOV BYTE PTR [DI], 'C'
INC BUFF_END
INSERT_CON: CMP BX, 0
JZ INSERT_END
INC DI
JMP INSERT_LP1
INSERT_END: POP DI
POP SI
POP BX
POP CX
POP AX
RET
INSERT ENDP
CODE ENDS
END MAIN
字符串排序是CMP AL, [SI+1] 数组排序是CMP AX, [SI+2]
比较是否比C大的时候 CMP BYTE PTR [SI], ‘C’ 只要出现内存,就都加上类型PTR
其实我只要插入一次’C’,因此需要BX作为标号,标记我是不是真的已经插入了,插入了就结束了,否则"永动机"
- 4.字符串比较
STACK SEGMENT PARA STACK
DW 100H DUP(?)
STACK ENDS
DATA SEGMENT PARA
LEN EQU 120
STRING2 DB LEN-1
DB ?
DB 100 DUP(?)
STRING1 DB 'ZhangJiayuan',00h, '$'
NEW_LINE DB 0DH, 0AH, '$'
RESULT DB ?
DATA ENDS
CODE SEGMENT PARA
ASSUME CS:CODE, DS:DATA, SS:STACK
MAIN PROC FAR
MOV AX, DATA
MOV DS, AX
MOV ES, AX
MOV AH, 0AH
INT 21H
MOV CL, STRING2+1
XOR CH, CH
MOV SI, OFFSET STRING2+2
ADD SI, CX
MOV BYTE PTR [SI], 00H
INC SI
MOV BYTE PTR [SI], '$'
MOV DX, OFFSET NEW_LINE
MOV AH, 9
INT 21H
MOV DX, OFFSET STRING2 +2
MOV AH, 9
INT 21H
MOV DX, OFFSET NEW_LINE
MOV AH, 9
INT 21H
MOV SI, OFFSET STRING1
PUSH SI
MOV DI, OFFSET STRING2 +2
PUSH DI
CALL SORT
EXIT: MOV AX, 4C00H
INT 21H
MAIN ENDP
SORT PROC NEAR
PUSH BP
MOV BP, SP
PUSH SI
PUSH DI
MOV SI, [BP+6]
MOV DI, [BP+4]
PUSH AX
PUSH DX
CLD
SORT_LP1: LODSB
CMP AL, BYTE PTR [DI]
JA L1
JB L2
CMP AL, 00h
JZ L3
INC DI
JMP SORT_LP1
L1: MOV BYTE PTR RESULT, '>'
JMP SORT_END
L2: MOV BYTE PTR RESULT, '<'
JMP SORT_END
L3: MOV BYTE PTR RESULT, '='
SORT_END: MOV DX, OFFSET STRING1
MOV AH, 9
INT 21H
MOV DX, OFFSET NEW_LINE
MOV AH, 9
INT 21H
MOV DL, RESULT
XOR DH, DH
MOV AH, 2
INT 21H
MOV DX, OFFSET NEW_LINE
MOV AH, 9
INT 21H
MOV DX, OFFSET STRING2 +2
MOV AH, 9
INT 21H
POP DX
POP AX
POP DI
POP SI
POP BP
RET
SORT ENDP
CODE ENDS
END MAIN
重点是STRING2+2,找输入字符的长度时,MOV CL, STRING2+1 XOR CH,CH
临考复习
-
1.复习基础知识
41h-39h = 16+1-9 = 8h 其实ADD AL, 7
-
2.字符输入输出程序
- 1.输入十进制数字 sub al, 30h
- 2.一个字的十六进制显示 add dl, 30h !!!
- 3.十六进制->十进制 add al, 30h
- 1.查表法:乘
- 2.除10法
- 3.利用字符串显示 result db 5 dup(?)
-
3.冒泡排序 PUSH CX POP CX 【注】字符串排序与数组排序
-
4.字符串 CLD/STD在SB前面