本文转载自厉害的
孔姐姐
的 博客 。由一只孔姐姐的小迷弟负责排版和整理~
指令集:所有指令的集合
机器指令:用二进制序列(0、1)代码书写。硬件只能识别、存储和运行机器指令
符号指令:用字符串形式的序列(包含字符串形式的操作码、操作数)
指令长度:机器指令长度为 1~16 字节
指令地址:多字节指令会占用连续的内存单元,存放指令第一个字节的内存地址,称为 指令地址
指令存放:
小端法
(1)寄存器操作数:存放于通用寄存器(8 个)中
(2)段寄存器和程序指针: CS:IP 决定取哪条指令
(3)标志存储器:分 状态标志
、控制标志
C:最高位产生 借位或进位标志。进位 C=1
O:溢出标志。溢出 O=1
Z:零标志。结果为 0 则 Z=1
S:符号标志。就是结果的符号位。
P:奇偶标志。低 8 位中 1 的个数为偶数 P=1
A:辅助进位标志。低半字节向高半字节有进位或借位,A=1
D:方向标志。D=1 时串操作时自动减量
I:中断标志。I=1 时允许 CPU 接收外部的中断请求
注意 O 标为 0,加数与被加数是 1,结果也是 1,相同。O 标为 0
但是,在讨论是否溢出的时候,就要分情况讨论了。(有 O,无 C)
立即数:包含在指令中 ------------ 立即寻址
寄存器操作数:存放于 CPU 的某个寄存器中 ---------------- 寄存器寻址
内存操作数:存放于存储器中 ------------------ 存储器寻址
I/O 端口操作数:存放于 I/O 端口中
MOV AL,OFFSET BUF ;(是不是可以理解成,取出了偏移量,就取得了操作数)
MOV CX,0A234H ;( A~F 开头的数字,加上 0 作为前缀)
MOV EAX,12345678H
INC SI
使用段页式管理部件,将指令中的逻辑地址转化为对应的物理地址,(对应第二章实模式下,存储地址空间)再通过总线系统访问实际的物理存储单元。
段寄存器名称,也称为段超越前缀,是存放操作数的存储单元所在的逻辑段:如 CS、DS、SS、ES。而这些段寄存器中存放逻辑段的段基址(逻辑段在存储空间中的位置)。 16 位
偏移地址表达式,给出偏移地址,也称偏移量,相对于逻辑段段首单元的地址偏移量。16 位
(1)直接寻址:偏移地址 用数值、变量名表示
ADD AL,DS:[45H] ;这里段寄存器名称一定要加
MOV AX,ES:[1000H]
MOV AX,DS:BUF ;也可以写成 MOV AX,BUF
INC BUF+2
用变量名代表偏移地址,变量名在汇编的时候,会给出实际的偏移地址,所以 BUF+2,BUF 都是直接寻址。
(2) 寄存器间接寻址:间接寻址、间址
注意,这里是要从内存中取操作数,但是通过寄存器找的而已,差不多这意思?
MOV AX,[BX]
MOV AX,[SI]
(3)基址寻址:
MOV AX,[BX+2]
(4)变址寻址:
MOV AL,[SI+2]
有比例因子的变址寄存器的寻址位数都是 32 位的(就是 E。。。)
无比例因子的变址寻址方式只能使用 SI、DI
MOV SI,BUF 单元的偏移地址
MOV AH,SS:[SI+3]
(5) 基址 + 变址寻址:
MOV AL,[BX+SI+2]
总结一下寻址方式:
BX、SI、DI 对应的一定是数据段,BP 对应的一定是堆栈段
SI、DI 不能做基址寄存器。 [SI] 是间址, [SI+3] 是变址,[BX] 是间址,[BX+3] 是基址。
[BX]、[SI] 是间址
[DX] 是不对的,没有 DX 的寄存器
源程序 ------------ .asm ----------------------- .obj --------------------- .exe
EDIT 编辑 TASM 汇编 TLINK 链接
.exe
.com
指令性语句: 符号指令(机器指令):CPU 执行
指示性语句:伪指令和宏指令
JUMP 标号 ;这里的标号就是符号地址
标号:定义在代码段中。
变量:定义在 DS、SS、ES 中
数据定义伪指令: DB DW DD DF/DQ/DT
符号定义伪指令:EQU =
注意的点:
①DB 可以定义用单引号括起来的很长的字符串,但是都是按照从上往下,地址由低向高排的
但是 DW 只能存单引号括起来的一个或者两个字符
(1)数值表达式:标号和变量、常量(立即数、字符串常数、符号常数)、数值运算符(算术运算符、逻辑运算符、关系运算符、数值回送运算符)
字符串常数是用单引号括起来的一个或多个字符,在汇编结束后,会转换成对应的 ASCII 码。'12’会转换为 3132H。
关系运算只能对两个数字,或者同一个逻辑段的两个存储单元中的数。如果为真,则结果为 0FFFF H,,假的结果为 0
数值回送运算符中:
SEG 取出数据段的段基址
OFFSET 取出,在逻辑段中相对于段首的偏移地址
$ 返回当前汇编地址计数器的值
MOV AX,SEG DATA ;SEG 可省略
MOV AX,SEG DATA
MOV DS,AX
BUF DB 10H,20H,30H
MOV BX,OFFSET BUF
MOV AH,[BX+1]
执行后(AH)=20H
BUF DB 'HELLO NUPT'
COUNT EQU $-BUF
汇编结束后,COUNT 的值为 10
(2)地址表达式:汇编结束后,是变量或者标号所在逻辑段的偏移地址值
包括 方括号运算符 [] 和变量的地址表达式、属性操作符(PTR、LOW/HIGH、SHORT、THIS)
MOV AH,BUF[1]
;等效于
MOV AH,BUF+1
PTR 操作符:
属性不对,必须用 PTR
(源操作数是立即数),除了直接寻址的内存操作数,都必须加 PTR
(5)操作项:包括操作码助记符、伪指令助记符
伪指令:数据定义伪指令(DB DW DD)、数据定义伪指令(EQU = )
传送指令、算术运算指令、转移和调用指令、逻辑运算和移位指令、串操作指令、处理机控制指令
通用传送:MOV MOVSX MOVZX LEA 指针传送指令 LAHF/SAHF XCHG
MOV XCHG 源目操作数不能同时为内存操作数,不能将立即数直接传送到段寄存器
堆栈操作指令 PUSH POP , 栈底是高地址单元。
PUSH 之后,(SP) - 2 -> (SP) ; POP 之后,(SP) + 2 -> (SP)
这里有些例题,挺有意思的
ADD SUB 不能同时为内存操作数,不能同时为段寄存器 ADC SBB 为二进制数带进位
INC DEC: INC [BX], 单操作数,直接寻址必须加 PTR
NEG:求补指令,但是不是求补码! 0 - 目标操作数
MUL 乘数
字节乘法: AL ---->AX AL×乘数 = AX
字乘法:AX—>DXAX 高位 DX, 低位 AX AX×乘数 = DXAX
双字乘法:EAX---->EDXEAX
字节除法:被除数 AX,商 AL, 余数 AH AX÷除数 = AL···AH
字除法:DXAX÷除数 = AX···DX 与字节除法的存储方式类似,余数覆盖高位的被除数,商覆盖低位的被除数。
(里面 2 个,外面 2 个,成对覆盖,方便记忆。。。)
CMP BYTE PTR [BX],45H
JC NEXT
我认为考试应该只考组合 BCD 码(比如 8421 码),希望不要打脸,我要复习不完了。。。
记得第一章有 BCD 码的结果调整方法:
低四位有进位,+06H
低四位非法,+66H
高四位非法,+60H
我们在给计算机在存储数值的时候,都是用的 XXH,如果直接 ADD AX,BX, 那么进行的是真实的, 16 进制的加法。09H+06H=0FH
如果需要进行 BCD 码运算,就得用到 BCD 码的调整指令。09H +06H =15H
(这里为什么有 H 啊,H 不是十六进制数吗?其实可以这样理解,BCD 码中的 H 是没有实际意义的,只是为了方便 BCD 码的简写)
;用算术运算指令实现十进制的计算1234+5678
N1 DW 1234H
N2 DW 5678H
SUM DW ?
;-----字加----
MOV AX,N1
ADD AX,N2
DAA
MOV SUM,AX
;-----字节加----
MOV AL,BYTE PTR N1
ADD AL,BYTE PTR N2
DAA
MOV BYTE PTR SUM,AL
MOV AL,BYTE PTR N1+1
ADD AL,BYTE PTR N2+1
DAA
MOV BYTE PTR SUM+1,AL
包括:无条件转移 JMP 、条件转移指令、子程序调用与返回指令、软件中断与返回指令
JMP 标号 只考察段内直接转移(只修改 IP,CS 值不变) 标号是符号指令的地址
条件转移指令有 3 个表格要记(根据状态位的,无符号数的,有符号数的)
这三个表里,JC(C=1)、 JZ(Z=1)、 JNC、 JNZ
JA(jump above) JC(C=1)
JG(jump greater,x>y) JGE(x>=y) 常用
LOOP:
MOV CX,5
AGAIN:
....
LOOP AGAIN
子程序 XYZ 调用: CALL XYZ
掌握段内直接调用,其原理是,首先将 CALL 指令的下一条指令的地址,即断点的偏移地址压入堆栈中保存,然后将子程序的入口偏移地址 ->(IP),(SP-2)->SP,程序由主程序转到子程序
;主函数中
CALL XYZ
;子程序
XYZ PROC
....
....
....
RET
XYZ ENDP
软件中断与返回指令:
INT n
在第四章中,会疯狂地用到
取反 NOT
与运算 AND:使特定位为 0
或运算 OR:使特定位为 1
XOR:使特定位取反,,,用 1 异或 x, 对 x 取反
TEST:测试,与
运算,影响标志位
移位指令;
开环:SAL SAR SHL SHR
闭环:RCL RCR ROL ROR
左移、右移看最后一个字母 left or right
逻辑、算术运算看中间 algorithm
带 R 的是有循环 recycle?
有符号数 – 算术右移补符号位
开环的左移一定都补 0,因为毕竟左移是要乘 2 的
闭环带 C 的,那就是含进位的,左移出来的那一位,不仅给了 C,也循环到了第 0 位
这里,应该是只要掌握
①源串定义在数据段,用 SI 间址访问
②目标串定义在附加段,用 EI 访问
③D=1(STD 使得 D=1),减址传送 D=0(CLD 使得 D=0),增址传送