980 likes | 1.27k Views
第四章 汇编语言基本概念 和 8086 指令系统. 4.1 汇编语言基本概念 4.2 Intel 80x86 系列 CPU 指令系统. 4.1 汇编语言基本概念. 计算机只能执行二进制的机器语言程序。. 源程序: 采用助记符写成的程序。 目标程序: 源程序翻译成的机器语言程序。 汇编过程(汇编) :将源程序翻译成目标程序的过程。 汇编由计算机执行 汇编程序 来完成。. 指令: 使 CPU 产生动作、并在程序执行时才处理的语句。 伪指令: 不产生 CPU 动作、在程序执行前由汇编程序处理的说明性语句。. 空格 :. ;.
E N D
第四章 汇编语言基本概念 和8086指令系统 4.1 汇编语言基本概念 4.2Intel 80x86系列CPU指令系统
4.1 汇编语言基本概念 计算机只能执行二进制的机器语言程序。 源程序:采用助记符写成的程序。 目标程序:源程序翻译成的机器语言程序。 汇编过程(汇编):将源程序翻译成目标程序的过程。 汇编由计算机执行汇编程序来完成。 指令:使CPU产生动作、并在程序执行时才处理的语句。 伪指令:不产生CPU动作、在程序执行前由汇编程序处理的说明性语句。
空格 : ; 标识符 操作助记符 空格 操作数 注释 汇编语言语句的组成 例如: CYCLE: ADD AX,02 DATA1 DB 20H,30H,40H DISPLAY PROC FAR 1. 标识符(非必需)——符号地址(内存单元首地址) 标号——写在指令前,后面加冒号 名称——写在伪指令前 可由字母(a~z),数字(0~9)及特殊符号(?、·、@、_、$)组成。字母打头或圆点符打头,字母不分大小写。
空格 : ; 名称 操作助记符 空格 操作数 注释 汇编语言语句的组成 2. 操作助记符(必需) 指明该语句的基本功能。 3. 操作数(非必需) 多个操作数用逗号“,”分隔。 4. 注释(非必需) 语句或程序段的说明,不可执行,汇编时不形成任何目标码。
常数和表达式 1.常数 (1)数字常量:十进制、八进制、十六进制、二进制等,缺省形式是十进制; (2)字符常量:用单引号括起来,存储的是该字符的ASCII码。 2.表达式 算术表达式、逻辑表达式和关系表达式。 算术操作符:+、-、*、/、MOD。 逻辑操作符:AND、OR、NOT、XOR。 关系操作符:EQ、NE、LT、GT、LE、GE。
常数和表达式 汇编语言中,表达式不能单独成句,只能作为语句的一部分。语句中表达式的求值在对源程序进行汇编连接时完成。 MOV BUF+2, AL ADD AL, VAL AND 0FH JMP AGAIN+3 MOV BL, VB LE VA
标号 变量 伪指令 一、标号 写在指令前,标示该指令的在内存中的存储地址——符号地址。 三种属性:段属性、偏移属性和类型。类型包括NEAR(段内)和FAR(段间)。 定义方法:在指令助记符前加上标识符和冒号。 例如 START: MOV AX, DATA
标号 变量 伪指令 二、变量 1. 变量定义 伪指令为变量申请固定长度的存储空间,并可以同时将相应的存储单元初始化。 变量名 DB表达式;定义字节变量 变量名 DW表达式;定义字变量 变量名 DD表达式;定义双字变量 变量名 DQ表达式;定义长字变量 变量名 DT表达式;定义一个十字节变量
标号 变量 伪指令 变量定义中的表达式可以是: ① 一个或多个常数或表达式。当为多个时中间用逗号隔开。 ② 带引号的字符串。 ③ 一个问号“?”。只留出相应的存储空间,不存入新的值。 ④ 重复方式。此时表达式部分的格式为: 重复次数 DUP (表达式)
0100:0000H 20H F 42H 04H 0100:0010H 41H 0001H 0002H 02H 43H 1 00H 2 00H 3 4 10H 3 44H 5 FDH 4 00H 6 05H 5 ? 7 45H ? 6 8 23H ? 7 9 01H 8 00 A 00H 9 00 30H ? B A C B 31H ? D 32H ? C E 33H D ? 标号 变量 伪指令 DATA1 DB 20H DATA2 DW 0204H,1000H DATA3 DB (-1*3),(15/3) DATA4 DD 12345H DATA5 DB ‘0123’ DATA6 DW ‘AB’,’C’,’D’ DATA7 DB ? DATA8 DW ? DATA9 DB 2 DUP (00) DATA10 DW 2 DUP (?)
标号 变量 伪指令 2. 变量的属性 段地址(SEG):变量所在段的段地址。 偏移地址(OFFSET):变量所在段内的偏移地址。 类型(TYPE):变量的类型所定义的每个变量所占据的字节数,对于DB、DW、DD、DQ、DT定义的变量其类型分别为1、2、4、8、10。 长度(LENGTH):变量定义时,一个变量名所定义的变量个数。在含有DUP操作符的变量中,变量名所定义的变量个数为定义格式中的重复次数。在其它各种变量定义中,每个变量名所定义的变量个数均为1。 大小(SIZE):变量定义语句中,分配给一个变量名的所有变量的总的字节数,其值为该变量的类型与长度的乘积。
属性操作符及表达式 (1)获取属性的操作符 例如: SEG DATA1 OFFSET DATA2 LENGTH DATA6 TYPE DATA6 SIZE DATA 9 表达式不能构成单独的语句,只能是语句的一个成分。 例如: MOV AX,SIZE DATA9 MOV BL,TYPE DATA9
属性操作符及表达式 (2)PTR操作符 格式:类型 PTR 表达式 功能:重新定义已定义的变量或标号的类型。 例如:若定义的变量DATA2为字型变量,则可以有 MOV BYTE PTR DATA2,AL
4.2 Intel 80x86系列CPU指令系统 • 4.2.1 数据传送类指令 • 4.2.2 算术运算类指令 • 4.2.3 逻辑运算类指令 • 4.2.4 移位指令和循环移位指令 • 4.2.5 处理机控制类指令 • 4.2.6 386及其后继机型新增指令
指令操作数的表达 r8 —— 任意一个8位通用寄存器 AH/AL/BH/BL/CH/CL/DH/DL r16 —— 任意一个16位通用寄存器 AX/BX/CX/DX/SI/DI/BP/SP reg —— 代表r8或r16 seg —— 段寄存器CS/DS/ES/SS m8 —— 一个8位存储器操作数单元 m16 —— 一个16位存储器操作数单元 mem —— 代表m8或m16 i8 —— 一个8位立即数 i16 —— 一个16位立即数 imm —— 代表i8或i16 dst —— 目的操作数 src —— 源操作数
学习指令的注意事项 • 指令的功能——该指令能够实现何种操作。通常指令助记符就是指令功能的英文单词或其缩写形式。 • 指令支持的寻址方式——该指令中的操作数可以采用何种寻址方式。 • 指令对标志的影响——该指令执行后是否对各个标志位有影响,以及如何影响。 • 其他方面——该指令其他需要特别注意的地方,如指令执行时的约定设置、必须预置的参数、隐含使用的寄存器等。
4.2.1 数据传送类指令 把数据从一个位置传送到另一个位置。 14条指令分5组: 1. 通用数据传送:MOV XCHG XLAT 2. 堆栈操作:PUSH POP 3. 标志寄存器传送:LAHF SAHF PUSHF POPF 4. 地址传送:LEA LDS LES 5. 输入输出:IN OUT
4.2.1 数据传送类指令 • 数据传送是计算机中最基本最重要的一种操作,传送指令也是最常使用的一类指令。 • 除标志寄存器传送指令外,均不影响标志位。 • 本节要求: 重点掌握: MOV PUSH POP 特别熟悉:XCHG XLAT LEA 一般了解: LAHF SAHF PUSHF POPF LDS LES 以后展开: IN OUT
传送指令MOV(move) 功能:把一个字节或字的操作数从源地址传送至目的地址。 MOV reg/mem,imm;立即数送寄存器或主存 MOV reg/mem/seg,reg;寄存器送(段)寄存器或主存 MOV reg/seg,mem;主存送寄存器 MOV reg/mem,seg;段寄存器送寄存器或主存
传送指令MOV(move) 例1:立即数传送 MOV AL,4 ;AL←4,字节传送 MOV CX,0FFH ;CX←00FFH,字传送 MOV SI,200H;SI←0200H,字传送 MOV BYTE PTR [SI],0AH ;DS:[SI] ←0AH,BYTE PTR 说明是字节操作 MOV WORD PTR [SI+2],0BH ;DS:[SI+2] ←0BH ;DS:[SI+3] ←00H ,WORD PTR说明是字操作 注意:要明确指令是字节操作还是字操作。
传送指令MOV(move) 例2:寄存器传送 例3:存储器传送 MOV AX,BX MOV AH,AL MOV DS,AX MOV [BX],AL MOV AL,[BX] MOV DX,[BP] ;DX←SS:[BP] MOV ES,[SI] ;ES←DS:[SI] 例4:段寄存器传送 MOV [SI],DS MOV AX,ES 注意事项
传送指令MOV(move) 两个操作数的类型要一致 绝大多数双操作数指令,除非特别说明,目的操作数与源操作数必须类型一致,或者同为字,或者同为字节,否则为非法指令。 MOV AL,050AH ;非法指令:050AH为字,而AL为字节 1. 寄存器有明确的字节或字类型,有寄存器参与的指令其操作数类型就是寄存器的类型。 2. 对于存储器单元与立即数同时作为操作数的情况,必须显式指明。 BYTE PTR指示字节类型,WORD PTR指示字类型。
传送指令MOV(move) 两个操作数不能都是存储器 8086指令系统不允许两个操作数都是存储单元(除串操作指令),没有主存至主存的数据传送。 要实现这种传送,可通过寄存器间接实现。 例5:buffer1单元的数据传送到buffer2单元 MOV AX,buffer1 ;AX←buffer1(将buffer1内容送AX) MOV buffer2,AX ;buffer2←AX ;这里buffer1和buffer2是两个字变量 ;实际表示直接寻址方式
传送指令MOV(move) 段寄存器的操作有一些限制 不允许立即数传送给段寄存器 MOV DS,100H;非法指令:立即数不能传送段寄存器 不允许直接改变CS值 MOV CS,[SI];不允许使用的指令 不允许段寄存器之间的直接数据传送 MOV DS,ES ;非法指令:不允许段寄存器间传送
取有效地址指令LEA(load EA) 功能:将存储器操作数的有效地址传送至指定寄存器中 LEA r16,mem;r16←mem的有效地址 例5:有效地址的获取 MOV BX,0400H MOV SI,3CH LEA BX,[BX+SI+0F62H];BX=139EH ;BX得到的是主存单元的有效地址, ;不是物理地址,也不是该单元的内容
LDS r16,mem ;r16←mem, ;DS←mem+2 LDS指令将主存中mem指定的字送至r16,并将mem的下一字送DS寄存器 取地址指针指令 LDS LES LES r16,mem ;r16←mem, ;ES←mem+2 • LES指令将主存中mem指定的字送至r16,并将mem的下一字送ES寄存器 例6:地址指针的传送 MOV WORD PTR [3060H],0100H MOV WORD PTR [3062H],1450H LDS SI,[3060H] ;DS=1450H,SI=0100H LES DI,[3060H];ES=1450H,DI=0100H ;MEM指定主存的连续4个字节作为逻辑地址(32位的地址 ;指针),送入DS:REG或ES:REG。
LAHF ;AH←FLAGS的低字节 LAHF指令将标志寄存器的低字节送寄存器AH SF/ZF/AF/PF/CF状态标志位分别送入AH的第7/6/4/2/0位,而AH的第5/3/1位任意 标志传送指令LAHF SAHF SAHF ;FLAGS的低字节←AH • SAHF将AH寄存器内容送FLAGS的低字节 • 用AH的第7/6/4/2/0位相应设置SF/ZF/AF/PF/CF标志
数据交换指令XCHG(exchange) 功能:把两个地方的数据进行互换 XCHG reg,reg/mem; reg←→reg/mem 数据交换指令可以在寄存器与寄存器之间对换数据 数据交换指令可以在寄存器与存储器之间对换数据 数据交换指令不能在存储器与存储器之间对换数据
数据交换指令XCHG(exchange) 例7:寄存器与寄存器数据交换 MOV AX, 1234H;AX=1234H MOV BX, 5678H;BX=5678H XCHG AX, BX ;AX=5678H,BX=1234H XCHG AH, AL;AX=7856H 例8:寄存器与存储器数据交换 XCHG AX, [2000H] XCHG AL, [2000H]
字节转换指令XLAT(translate) 功能:将BX指定的缓冲区中、AL指定的位移处的一个字节数据取出赋给AL。 XLAT;Al←DS:[BX+AL] 1. 字节交换指令执行前: 在主存中建立一个字节表格,内容是要转换成的目的代码, 表格的首地址存放于BX,AL存放相对表格首地址的位移量。 2. 然后,执行字节交换指令: 将AL寄存器的内容转换为目标代码。 隐含寻址
19H 10H 09H 04H 01H 0100H 00H 字节转换指令XLAT(translate) 例9:代码转换 MOV BX,100H MOV AL,03H XLAT • 字节转换指令没有显式的操作数,但使用了BX和AL; 因为换码指令使用了隐含寻址方式。 • 隐含寻址方式——采用默认操作数的寻址方式。
堆栈操作指令 什么是堆栈? • 堆栈是一个“先进后出”的主存区域,位于堆栈段中,使用SS段寄存器记录其段地址。 • 堆栈只有一个出口,即当前栈顶。栈顶是地址较小的一端(低端),它用堆栈指针寄存器SP指定。 存储器 高地址 滑动 栈底 SP 栈顶 堆栈段 SS 0000H
堆栈操作指令 堆栈的操作 堆栈只有两种基本操作:进栈和出栈, 对应两条指令PUSH和POP。 PUSH r16/m16/seg ;进栈指令: ;SP←SP-2 ;SS:[SP]←r16/m16/seg POP r16/m16/seg ;出栈指令: ;r16/m16/seg←SS:[SP] ;SP←SP+2 进栈:先使堆栈指针SP减2,然后把一个字操作数存入堆栈顶部; 出栈:先把栈顶的一个字传送至指定的目的操作数,然后堆栈 指针SP加2。
存储器 存储器 SP SP 78H 12H -2 78H 12H +2 0000H 0000H 进 栈 出 栈 堆栈操作指令 堆栈操作的实例和图示 PUSH AX PUSH [2000h] POP AX POP [2000h]
堆栈操作指令 堆栈的特点 • 堆栈操作的单位是字,进栈和出栈只对字量 • 字量数据从栈顶压入和弹出时,都是低地址字节送低字节,高地址字节送高字节。 • 堆栈操作遵循先进后出原则 • 可用存储器寻址方式随机存取堆栈中的数据 • 堆栈常用来: • 临时存放数据 • 传递参数 • 保存和恢复寄存器
堆栈操作指令 例10:现场的保护和恢复 PUSH AX ;进入子程序后 PUSH BX PUSH DS ... POP DS ;返回主程序前 POP BX POP AX
PUSHF ;SP←SP-2 ;SS:[SP]←FLAGS PUSHF指令将标志寄存器的内容压入堆栈,同时栈顶指针SP减2 标志寄存器出入堆栈 POPF ;FLAGS←SS:[SP] ;SP←SP+2 • POPF指令将栈顶字单元内容送标志寄存器,同时栈顶指针SP加2
标志寄存器出入堆栈 例11:置位单步标志 PUSHF ;保存全部标志到堆栈 POP AX;从堆栈中取出全部标志 OR AX,0100H;设置D8=TF=1, ;AX其他位不变 PUSH AX;将AX压入堆栈 POPF;将堆栈内容取到标志寄存器, ;即FLAGS←AX
IN AL/AX, i8/DX ;AL/AX←I/O端口 输入IN指令将外设数据传送给CPU内的AL/AX 输入输出指令 功能:8086通过输入输出指令与外设进行数据传送。 OUT i8/DX, AL/AX ; I/O端口← AL/AX • 输出OUT指令将CPU内的AL/AX数据传送给外设 输入输出指令将在第4章详述
4.2.2 算术运算类指令 实现二进制(和十进制)数据的四则运算 1. 加法运算:ADD ADC INC 2. 减法运算:SUB SBB DEC NEG CMP 3. 乘法运算:MUL IMUL 4. 除法运算:DIV IDIV 5. 符号扩展:CBW CWD 6. 十进制调整:DAA DAS AAA AAS AAM AAD
4.2.2 算术运算类指令 • 四则运算是计算机经常进行的一种操作。算术运算指令也是经常使用的一类指令。 • 请注意算术运算指令对标志的影响。 重点掌握:ADD/ADC SUB/SBB INC/DEC CMP 比较熟悉:NEG MUL/IMUL DIV/IDIV 一般了解: CBW CWD 认真理解:DAA DAS AAA AAS AAM AAD
ADD reg,imm/reg/mem;reg←reg+imm/reg/mem ADD mem,imm/reg;mem←mem+imm/reg 加法指令ADD(add) ADD指令将源与目的操作数相加,结果送到目的操作数。 ADD指令按状态标志的定义相应设置0或1。 ADD AL,07H ADD [200H],AL ADD BYTE PTR [200H],07H
ADC reg,imm/reg/mem;reg←reg+imm/reg/mem+CF ADC mem,imm/reg;mem←mem+imm/reg+CF 带进位加法指令ADC(add with carry) ADC指令将源与目的操作数相加,再加上当前进位CF标志,结果送到目的操作数。 ADD指令按状态标志的定义相应设置0或1 。 ADC指令主要与ADD配合,实现多精度加法运算。 双字加法
带进位加法指令ADC(add with carry) 例13:无符号双字加法运算 MOV AX,4652H ;AX=4652H ADD AX,0F0F0H ;AX=3742H,CF=1 MOV DX,0234H ;DX=0234H ADC DX,0F0F0H ;DX=F325H,CF=0 ;DX.AX = 0234 4652H ; + F0F0 F0F0H ; = F325 3742H
增量指令INC(increment) INC指令对操作数加1(增量)。INC指令不影响进位CF标志,按定义设置其他状态标志。 INC reg/mem;reg/mem←reg/mem+1 INC指令和DEC指令都是单操作数指令。 他们主要用于对计数器和地址指针的调整。 INC BX INC BYTE PTR [BX] 相关指令:DEC
SUB reg,imm/reg/mem;reg←reg-imm/reg/mem SUB mem,imm/reg;mem←mem-imm/reg 减法指令SUB(subtract) SUB指令将目的操作数减去源操作数,结果送到目的操作数。 SUB指令按照定义相应设置状态标志。 SUB AL,07H SUB AL,[200H] SUB WORD PTR [200H],4652H
SBB reg,imm/reg/mem;reg←reg-imm/reg/mem-CF SBB mem,imm/reg;mem←mem-imm/reg-CF 带借位减法指令SBB(subtract with borrow) SBB指令将目的操作数减去源操作数,再减去借位CF(进位),结果送到目的操作数。 SBB指令按照定义相应设置状态标志。 SBB指令主要与SUB配合,实现多精度减法运算。 双字减法
带借位减法指令SBB(subtract with borrow) 例14:无符号双字减法运算 MOV AX,4652H ;AX=4652H SUB AX,0F0F0H ;AX=5562H,CF=1 MOV DX,0234H ;DX=0234H SBB DX,0F0F0H ;DX=1143H,CF=1 ;DX.AX = 0234 4652H ; - F0F0 F0F0H ; = 1143 5562H
减量指令DEC(decrement) DEC指令对操作数减1(减量)。DEC指令不影响进位CF标志,按定义设置其他状态标志。 DEC reg/mem;reg/mem←reg/mem-1 INC指令和DEC指令都是单操作数指令。 他们主要用于对计数器和地址指针的调整。 DEC SI DEC BYTE PTR [SI] 相关指令:INC
取负指令NEG(negative) NEG指令对操作数执行求补运算:用零减去操作数,然后结果返回操作数。 NEG指令对标志的影响,与用零作减法的SUB指令一样。 NEG reg/mem;reg/mem←0-reg/mem 正数——绝对值相同的负数的补码; 负数——绝对值相同的正数.