1 微机原理及应用 主讲:谢维成 http://xweicheng.ys168.com scxweicheng@yahoo.com.cn 2 调试程序 DEBUG DEBUG.exe 是 DOS提供的一个调试汇编语言程 序的程序 每个版本的 DOS都带有该程序。 DEBUG程序采用的是命令行方式 使用不方便,但 实用性强 . 是学习汇编语言程序、计算机硬件等课程的有效 工具 . 其他调试程序 : Turbo Debugger ( TD.exe ) Code View Softice 3 DEBUG 主要命令一览 命令 功能简介 R 显示、修改寄存器内容 RF 显示、 修改 PSW内容 A 汇编指 令 U 反汇编 T 单步、多步执行指令 P 单步、多步执行指令 G 连续执 行指 令 D 显示内 存内 容 E 修改内 存内 容 W 将内存块写入文件 L 将文件调入内存 I 读入端口的内容 O 将数据写入端口 Q 退出 DEBUG,返 回 DOS 4 DEBUG程序的具体作用 : 1. 查看 /修改寄存器 , 内存单元的内容; 2. 学习寻址方式和指令系统 ; 3. 了解计算机取指令 , 执行指令的工作过程; 4. 调试有问题的汇编语言程序。 5 注意: DEBUG下符号与标志的对应关系 《实验指导书》附录 标志名 称 1 0 溢出标 志 OF OV NV 方向标 志 DF DN UP 中断标 志 IF EI DI 符号标 志 SF NG PL 零标志 ZF ZR NZ 辅助标 志 AF AC NA 奇偶标 志 PF PE PO 进位标 志 CF CY NC 6 课后可参照下列步骤做实验 : D:\>DEBUGY ;进入 DEBUG -R Y ;查看当前各寄存器的内容 AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1271 ES=1271 SS=1271 CS=1271 IP=0100 NV UP EI PL NZ NA PO NC 1271:0100 B83412 MOV AX,1234 -D 0 : 0 Y ;查看 0: 0~7FH内存块的内容 0000:0000 9E 0F C9 00 65 04 70 00-16 00 EB 07 65 04 70 00 ....e.p.....e.p. 0000:0010 65 04 70 00 54 FF 00 F0-58 7F 00 F0 F5 E7 00 F0 e.p.T...X....… 、、、、、、 -U FFFF : 0 Y ;反汇编 FFFF:0 处的指令 FFFF:0000 CD19 INT 19 FFFF:0002 E000 LOOPNZ 0004 、、、、、、 7 -A Y ;汇编一条指令 1271:0100 MOV AX,1234 1271:0103 -T =100 Y ;执行该指令 AX=1234 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1271 ES=1271 SS=1271 CS=1271 IP=0103 NV UP EI PL NZ NA PO NC 1271:0103 E9C300 JMP 01C9 -R Y ;查看指令执行后结果 AX=1234 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000 DS=1271 ES=1271 SS=1271 CS=1271 IP=0103 NV UP EI PL NZ NA PO NC -Q Y ;退出 DEBUG D:\> 8 3.4.2 算术运算指令 算术运算指令 1.加法指令 2.减法指令 3.乘法指令 4.除法指令 9 (3) 加 加 1指令 指令 INC( ( 单操作数指令) 单操作数指令) 格式: INC reg INC reg/mem 例 : INC AL INC BYTE PTR[BX+4] 本指令除CF外对其余标志均有影响。 (4)BCD码的加法十进制调正指令 AAA和 DAA ? AAA 本指令对在 AL中的由 两个未组合的B CD码 相加后的结果进行调正,得到一个正确的未组 合的BCD码。 10 例1 : MOV AL,08 0000 1000 ADD AL,09 +0000 1001 0001 0001 结果应为17,而计算机相加为11H,原因在 于运算过程中,如遇到低4位往高4位产生进位时 (此时AF=1)按逢十六进一的规则,但BCD码要 求逢十进一,因此只要产生进位就会丢掉一个6, 这就要进行加6调正。 11 实际上当低4位的结果>9(即A~F之间)时, 也应进行加6调正。 如上面的结果进行加6得: 0001 0001 + 0000 0110 0001 0111 12 AAA指令的调正步骤: 如AL的低4位>9或AF=1,则: ① (AL)←(AL)+6,(AH)←(AH)+1,AF←1 ② (AL)←((AL)∧0FH) ③CF←AF 否则(AL)←((AL)∧0FH) 再来看前例,用如下程序段可得正确结果 MOV AL,08H ADD AL,09H AAA 13 例2 : 计算2658+3619=? 设被加数和加数的每一位都以ASCII码形式存 放在内存中,低位在前,高位在后,另留出5个 单元存相加的结果。 如下页图3-13示 14 36H 32H 38H 35H STRING1 ‘8’ 被 加 数 ‘5’ ‘6’ ‘2’ 39H 31H 36H 33H ... ‘9’ 数 据 段 STRING2 ‘1’ 加 数 ‘6’ ‘3’ ... SUM 结 果 图 3-13 15 程序段如下: LEA SI, STRING1 ;取 STRING1偏址送 SI LEA DI, STRING2 ;取 STRING2偏址送 DI LEA BX, SUM ; 取 SUM偏址送 BX MOV CX, 4 CLC ;清进位标志 CF AGAIN: MOV AL, [SI] ADC AL, [DI] ;带进位加 AAA ;未组合的 BCD码调正 MOV [BX], AL ;送和的结果至 SUM INC SI ; (SI)+1 INC DI ; (DI)+1 INC BX ; (BX)+1 DEC CX ; (CX)-1 JNZ AGAIN ;若 (CX) ≠ 0,则转 AGAIN 16 根据程序请为SUM填写出结果 ,若最高位有进 位,程序如何修改? 从此例不难看出, AAA又被称为 加法的ASCII调 正指令。 AAA指令只影响AF和CF,其余标志无定义。 17 ?DAA 两个组合的BCD 码相加结果在 AL中,通过 DAA调正得到一个正确的组合的BCD码. 指令调正方法: 若AL的低4位>9 或 AF=1 则(AL)←(AL)+6,且AF←1 若AL的高4位>9 或 CF=1 则(AL)←(AL)+60H,且CF←1 与AAA不同,DAA指令不改变AH的内容。 DAA指令对OF无定义,但影响所有其它标志。 18 举例 : 0100 1000 MOV AL,48H +0111 0100 MOV BL,74H 1011 1100 ADD AL,BL + 0110 0110 DAA 1 0010 0010 (进位) 执行ADD后,(AL)=BCH,高4位低4位均大于9, 故DAA指令执行加66调正,最后结果为: (AL)=22H,CF=1,AF=1 使用A AA和D AA这两条指令时,应紧跟在 ADD或 ADC指令之后。 19 2. 减法指令 减法指令 8086/8088共有7条减法指令 (1) 不考虑借位的减法指令SUB 其操作数格式同ADD,即 SUB ac,data SUB mem/reg,data SUB mem/reg1,mem/reg2 例: SUB AL,60H SUB [BX+20H],5678H SUB AX,CX 20 (2) 考虑借位的减法指令 考虑借位的减法指令 SBB 本指令在形式上和功能上都和SUB类似,只 是相减时还应减去CF的值。 例: SBB AX,CX SBB WORD PTR[SI],2080H SBB指 令 主 要用于多字节的减法。因无符号数 的小数减大数时,不够减而产生借位 ,此时进位 标志CF=1。 21 (3) 减 减 1指令 指令 DEC 操作数格式:DEC reg DECmem/reg 例: DEC CL DEC BYTE PTR[DI+2] 以 上 三 条指令除DEC不影响CF外,都对标志位 有影响 。 22 (4) 求补指令 求补指令 NEG 因对一个操作数取补码相当于用0减去此操作 数,故NEG执行的是减法运算。 例: NEG AL ;对AL中的数取补码 若(AL)=0,执行后(AL)=0,CF=0 若(AL)=FCH, 执行后(AL)=04H,CF=1 FCH是-4的补码,执行后(AL)=04,故利用NEG指 令可得到 负数的绝对值 。 如果操作数的值为80H(-128)或8000H (- 32768),则执行求补指令后,结果不变,但OF=1。 本指令对6个标志位均有影响. 23 (5) 比较指令 比较指令 CMP(操作数格式同 操作数格式同 SUB) CMP也是执行两个操作数相减,但不送回结果, 其结果只反映在标志位上。 例 : CMP AL,0AH ;AL与0AH比较 CMP CX,SI ;CX与SI比较 CMP DI,[BX+03] ;DI与存储器比较 比较指令影响所有标志位。 如何根据标志位来判断两个操作数的比较结 果呢? 若两个所比较的数相等,则ZF=1,否则ZF=0 这样根据ZF就可判断两个数是否相等。 24 若两个数不相等,如何根据标志位来判断谁大 谁小呢?分两种情况考虑: ①比较的是两个无符号数 若CF=0,则被减数大,因大数减小数无须借位. 若CF=1,则被减数小。 ②比较的是两个有符号数 若两个数都是正数或负数时,相减不溢出(即 OF=0),可用S F来判断,若S F=0,表示被减数大,S F=1 则反之。 25 若比较的数中有一个为正,另一个为负,此时 不能单看SF,还需考虑OF,判别条件: OF=0时,若 SF=0 被减数大;若SF=1 减数大. OF=1时,若SF=1 被减数大;若SF=0 减数大. 也可归纳为: OF⊕ SF=0时(或SF=OF),被减数大. OF⊕ SF=1时(或SF=OF),减数大. 比较指令在使用时,一般在其后紧跟一条条件 转移指令,判断比较结果的转向。 26 例如有符号数比较结果的条件转移指令: JG/JNLE; 大于转移,条件OF ⊕ SF=0,且ZF=0 JLE/JNG; 小于或等于转移,条件OF ⊕ SF=1或ZF=1 举例 :比较AL、BL、CL中带符号数的大小,将最小 数放在AL中。程序段如下: CMP AL,BL ;AL和BL比较 JNG BBB ;若AL≤BL,则转 XCHG AL,BL ;若AL>BL,则交换 BBB: CMP AL,CL ;AL和CL比较 JNG CCC ;若AL≤CL,则转 XCHG AL,CL ;若AL>CL,则交换 CCC: INT 20H ;返回DOS 27 (6) BCD码的减法十进制调正指令 码的减法十进制调正指令 AAS和 和 DAS AAS 对 AL中由两个 未组合的BCD码 相减的结 果进 行调正。 调正操作为: 若AL的低4位>9或AF=1,则: ①(AL)←(AL)-6,(AH)←(AH)-1,AF←1 ②(AL)←((AL)∧0FH) ③C F← AF 否则:(AL)←((AL)∧0FH) 28 举例 :16-8=? 0000 0110 MOV AX,0106H -0000 1000 MOV BL,08H 1111 1110 SUB AL,BL - 0000 0110 AAS 1111 1000 ∧0000 1111 0000 1000 结果为:(AL)=08H,(AH)=0,CF=AF=1 29 DAS 对两个组合的BCD 码减法进行调正 结果应在 AL中。调正操作为: 若AL的低4位>9 或 AF=1,则: (AL)←(AL)-6, 且AF←1 若AL的高4位>9 或 CF=1,则: (AL)←(AL)-60H,且CF←1 DAS对OF无定义,但影响其余标志位。 AAS和DAS这两条指令在使用时要求紧跟在 减法指令之后。 30 3. 乘法指令 乘法指令 进行乘法时: 8位*8位 → 16位乘积 16位*16位→32位乘积 (1) 无符号数的乘法指令MUL(MEM/REG) 使用乘法指令对被乘数和乘积的存放地方均 有规定: 被乘数存放地方 乘积存放地方 对字节乘 AL AX 对字乘 AX DX,AX 例: MUL BL ;AL* BL,乘积在AX中 MUL CX ;AX* CX,乘积在DX和AX中 MUL BYTE PTR[BX] 31 (2) 有符号数乘法指令 有符号数乘法指令 IMUL(MEM/REG) 该指令在功能上和形式上与MUL类似,只是要 求两乘数均为有符号数。 例: IMUL CL ;AL中有符号数*CL中 有符号数 IMUL WORD PTR[SI] 举例 :设(AL)=FEH,(CL)=11H ①将FEH及11H均看做无符号数 执行MUL CL (可用二进制相乘算出来) 得(AX)=10DEH(=4318) 32 ②将FEH及11H均看做有符号数 执行IMUL CL 得(AX)=FFDEH(=-34) 其实这个结果也可以手算出来,FEH是用补码表 示的,它的真值为-2,先将两个数的绝对值相乘: 0000 0010 * 0001 0001 0000 0010 0000 0010 0000 0000 0010 0010 因负数乘正数乘积符号为负,需将上乘积绝对值 取补码,得:1111 1111 1101 1110 33 (3) BCD码的乘法十进制调正指令AAM 先执行MUL把两个非组合的BCD码相乘,结果在 AX中,再执行AAM进行调正,得到正确的结果。 调正的操作为: (AL)/0AH, (AH)←商 (AL)←余数 34 例: 要求进行如下十进制乘法运算:7*8=? 可编程如下: MOV AL,07H ; (AL)=07H MOV CL,08H ; (CL)=08H MUL CL ;(AX)=0038H AAM ;(AH)=05H,(AL)=06H 所得结果为非组合的BCD码。 该指令影响标志位PF、SF、ZF,对其余标志 位无定义。 35 4. 除法指令 除法指令 8086/8088 CPU执行除法运算,要求被除数字长为 除数字长的两倍,并对被除数、商及余数存放地方 有如下规定: 被除数 商 余数 字节除法 AX AL AH 字除法 DX:AX AX DX 36 (1) 无符号数除法指令 无符号数除法指令 DIV(MEM/REG) 例: DIV CL ;AX除以CL DIV WORD PTR[BX] ;DX:AX除以 BX,BX+1两存储器(16位) 若除数为 零 或 AL中商大于FFH ,(或 AX中商大于 FFFFH),则CPU产生一个 类型0 的内部中断。 (2) 有符号数除法指令 IDIV(MEM/REG) 本指令除要求有符号数相除外, 在功能上和形 式上与D IV类似。当然其商及余数均为有符号数, 且 余数符号总是与被除数符号相同。 37 例: 25除-4有两种结果: 商-6,余数+1 或 商-7,余数-3 给出的结果为前一种: 举例 : IDIV BX ;DX:AX除以BX IDIV BYTE PTR[SI];AX除以存储器(8位) 字节相除若 商超过了-128~+127 ,或字相除, 若 商超过了-32768~+32767 的范围,则自动产生 一个 类型0 的中断。 这两条除法指令对标志位无影响。 38 ? 下面讨论扩展指令,前面已指出除法运算要求 被除数字长是除数字长的两倍,若不满足则需对 被除数进行扩展,否则产生错误。 ? 对于无符号数除法扩展很简单,只需将AH或 DX清零即可。 ? 对有符号数而言,则是符号位的扩展.共提供 了两条指令。 39 (4) 将字节扩展成字的指令 CBW 指令的操作为: 若(AL)<80H 则(AH)←0 若(AL)≥80H 则(AH)←FF (5) 将字扩展为双字的指令 CWD 指令的操作为: 若(AX)<8000H 则(DX)←0 若(AX)≥8000H 则(DX)←FFFFH 这两条扩展指令均不影响标志位。