# 实验二:顺序程序设计 ## 一、实验名称 顺序程序设计 ## 二、实验目的 1. 掌握数据传送指令MOV的使用方法 2. 掌握算术运算指令ADD、SUB、MUL的使用方法 3. 掌握逻辑运算指令AND、OR的使用方法 4. 理解拆字程序的设计原理 5. 熟悉顺序程序的基本结构 ## 三、实验内容 ### 3.1 基础性实验 #### (1)数据传送和加法运算 **实验要求**:设X=25H,Y=30H,计算Z=X+Y **程序说明**: | 指令 | 功能 | |------|------| | MOV AL, 25H | 将25H传送到AL(X=25H) | | MOV BL, 30H | 将30H传送到BL(Y=30H) | | ADD AL, BL | AL = AL + BL = 55H | | MOV Z, AL | 将结果55H存入Z | #### (2)多字节加法运算 **实验要求**:实现32位数据加法(12345678H + 87654321H) **程序说明**: | 指令 | 功能 | |------|------| | MOV AX, 5678H | 被加数低16位 | | MOV DX, 1234H | 被加数高16位 | | MOV CX, 4321H | 加数低16位 | | MOV BX, 8765H | 加数高16位 | | ADD AX, CX | 低16位相加 | | ADC DX, BX | 高16位带进位相加 | #### (3)拆字程序 **实验要求**:将16位数ABCDH拆分为两个8位数 **程序说明**: | 指令 | 功能 | |------|------| | MOV AX, 0ABCDH | 16位数据送入AX | | MOV DL, AL | 保存低8位CDH到DL | | MOV CL, 8 | 设置移位计数 | | SHR AH, CL | AH右移8位,得高8位ABH | | MOV BH, AH | 高8位ABH存入BH | | MOV BL, DL | 低8位CDH存入BL | ### 3.2 加强性实验 #### (1)8位×8位乘法运算 **实验要求**:实现8位×8位乘法(12H × 34H) **程序说明**: | 指令 | 功能 | |------|------| | MOV AL, 12H | 被乘数12H送入AL | | MOV BL, 34H | 乘数34H送入BL | | MUL BL | AX = AL × BL = 0D68H | #### (2)多字节减法运算 **实验要求**:实现16位减法(9876H - 1234H) **程序说明**: | 指令 | 功能 | |------|------| | MOV AX, 9876H | 被减数送入AX | | MOV BX, 1234H | 减数送入BX | | SUB AX, BX | AX = AX - BX = 8642H | #### (3)逻辑运算(AND和OR) **实验要求**:对55H分别进行AND和OR运算 **程序说明**: | 指令 | 功能 | |------|------| | MOV AL, 55H | AL = 55H (01010101B) | | AND AL, 0FH | AL = 55H AND 0FH = 05H | | MOV BL, AL | 保存AND结果到BL | | MOV AL, 55H | 恢复AL = 55H | | OR AL, 0F0H | AL = 55H OR F0H = F5H | ## 四、实验步骤 ### 4.1 基础性实验步骤 #### 实验1:数据传送和加法运算 1. 进入DOS环境,加载DEBUG程序 2. 使用A命令输入以下程序: ``` -a 100 -mov al, 25 -mov bl, 30 -add al, bl -mov [110], al -int 20 ``` 3. 使用E命令在100:110处设置变量Z的存储空间 ``` -e 110:0 ``` 4. 使用G命令执行程序 ``` -g=100 ``` 5. 使用D命令查看结果 ``` -d 110:0 110:0 ``` #### 实验2:多字节加法运算 1. 进入DEBUG环境 2. 使用A命令输入32位加法程序 3. 执行程序并验证结果(DX:AX = 99999999H) #### 实验3:拆字程序 1. 进入DEBUG环境 2. 使用A命令输入拆字程序 3. 执行程序,观察BH和BL的值 ### 4.2 加强性实验步骤 #### 实验1:乘法运算 1. 进入DEBUG环境 2. 使用A命令输入乘法程序 3. 执行程序,验证AX=0D68H #### 实验2:减法运算 1. 进入DEBUG环境 2. 使用A命令输入减法程序 3. 执行程序,验证AX=8642H #### 实验3:逻辑运算 1. 进入DEBUG环境 2. 使用A命令输入逻辑运算程序 3. 执行程序,验证BL=05H,AL=F5H ## 五、程序代码 ### 5.1 基础性实验程序代码 #### 实验1:数据传送和加法运算 ```assembly ; 实验二基础性实验一:数据传送和加法运算 ; 程序功能:X=25H, Y=30H, Z=X+Y ; 计算25H + 30H = 55H,结果存入Z CODE SEGMENT ASSUME CS:CODE ORG 100H ; 程序装入地址 START: MOV AL, 25H ; X=25H传送到AL MOV BL, 30H ; Y=30H传送到BL ADD AL, BL ; AL = AL + BL = 25H + 30H = 55H MOV Z, AL ; 结果55H存入Z INT 20 ; 退出程序 Z DB ? ; 定义变量Z CODE ENDS END START ``` #### 实验2:多字节加法运算 ```assembly ; 实验二基础性实验二:多字节加法运算 ; 程序功能:实现32位数据加法 ; 被加数:12345678H,加数:87654321H,结果存入指定内存 CODE SEGMENT ASSUME CS:CODE ORG 100H START: MOV AX, 5678H ; 被加数低16位 MOV DX, 1234H ; 被加数高16位 MOV CX, 4321H ; 加数低16位 MOV BX, 8765H ; 加数高16位 ADD AX, CX ; 低16位相加 ADC DX, BX ; 高16位带进位相加 ; 结果:DX:AX = 99999999H INT 20 CODE ENDS END START ``` #### 实验3:拆字程序 ```assembly ; 实验二基础性实验三:拆字程序 ; 程序功能:将16位数拆分为两个8位数 ; 原始数据:ABCDH,拆分后:高8位=ABH,低8位=CDH CODE SEGMENT ASSUME CS:CODE ORG 100H START: MOV AX, 0ABCDH ; 16位数据AX=ABCDH MOV DL, AL ; 将AL(低8位)传给DL保存 MOV CL, 8 ; 设置移位计数 SHR AH, CL ; AH右移8位,得到高8位ABH MOV BH, AH ; 高8位存入BH MOV BL, DL ; 低8位CDH存入BL ; 结果:BH=ABH(高8位), BL=CDH(低8位) INT 20 CODE ENDS END START ``` ### 5.2 加强性实验程序代码 #### 实验1:8位×8位乘法运算 ```assembly ; 实验二加强性实验一:8位×8位乘法运算 ; 程序功能:实现8位×8位乘法 ; 被乘数:12H,乘数:34H,结果存入16位变量 CODE SEGMENT ASSUME CS:CODE ORG 100H START: MOV AL, 12H ; 被乘数12H存入AL MOV BL, 34H ; 乘数34H存入BL MUL BL ; AX = AL * BL = 12H * 34H = 0D68H ; 结果:AX=0D68H(16位乘积) INT 20 CODE ENDS END START ``` #### 实验2:多字节减法运算 ```assembly ; 实验二加强性实验二:多字节减法运算 ; 程序功能:实现16位减法运算 ; 被减数:9876H,减数:1234H,结果=8642H CODE SEGMENT ASSUME CS:CODE ORG 100H START: MOV AX, 9876H ; 被减数AX=9876H MOV BX, 1234H ; 减数BX=1234H SUB AX, BX ; AX = AX - BX = 9876H - 1234H = 8642H ; 结果:AX=8642H INT 20 CODE ENDS END START ``` #### 实验3:逻辑运算(AND和OR) ```assembly ; 实验二加强性实验三:逻辑运算(AND和OR) ; 程序功能:实现AND和OR逻辑运算 ; 数据:AL=55H,进行AND和OR运算 CODE SEGMENT ASSUME CS:CODE ORG 100H START: MOV AL, 55H ; AL=55H (01010101B) AND AL, 0FH ; AL = AL AND 0FH = 55H AND 0FH = 05H ; 此时AL=05H (低4位保留,高4位清零) MOV BL, AL ; 保存AND结果到BL MOV AL, 55H ; 恢复AL=55H OR AL, 0F0H ; AL = AL OR 0F0H = 55H OR F0H = F5H ; 此时AL=F5H (高4位置1,低4位不变) ; 结果:BL=05H(AND结果), AL=F5H(OR结果) INT 20 CODE ENDS END START ``` ## 六、实验结果 ### 6.1 基础性实验结果 #### 实验1:数据传送和加法运算结果 【此处需要截图】 截图应包含: - 程序输入过程 - 执行T命令单步执行,观察AL=25H - 执行T命令单步执行,观察BL=30H - 执行ADD指令后AL=55H - 执行后内存110处值为55H 预期结果:Z = 55H #### 实验2:多字节加法运算结果 【此处需要截图】 截图应包含: - 执行前DX:AX = 1234:5678 - 执行前CX:BX = 8765:4321 - 执行后DX:AX = 9999:9999 预期结果:12345678H + 87654321H = 99999999H #### 实验3:拆字程序结果 【此处需要截图】 截图应包含: - 执行前AX = ABCDH - 执行后BH = ABH,BL = CDH 预期结果:高8位 = ABH,低8位 = CDH ### 6.2 加强性实验结果 #### 实验1:乘法运算结果 【此处需要截图】 截图应包含: - 执行前AL = 12H,BL = 34H - 执行后AX = 0D68H 预期结果:12H × 34H = 0D68H(即十进制3428) #### 实验2:减法运算结果 【此处需要截图】 截图应包含: - 执行前AX = 9876H,BX = 1234H - 执行后AX = 8642H 预期结果:9876H - 1234H = 8642H #### 实验3:逻辑运算结果 【此处需要截图】 截图应包含: - 55H AND 0FH = 05H(BL=05H) - 55H OR 0F0H = F5H(AL=F5H) ### 6.3 实验数据记录表 **基础性实验数据记录** | 实验 | 输入数据 | 操作 | 结果 | |------|----------|------|------| | 实验1 | X=25H, Y=30H | X+Y | Z=55H | | 实验2 | 12345678H + 87654321H | 32位加法 | 99999999H | | 实验3 | AX=ABCDH | 拆字 | BH=ABH, BL=CDH | **加强性实验数据记录** | 实验 | 输入数据 | 操作 | 结果 | |------|----------|------|------| | 实验1 | AL=12H, BL=34H | 8位×8位乘法 | AX=0D68H | | 实验2 | AX=9876H, BX=1234H | 16位减法 | AX=8642H | | 实验3 | AL=55H | AND 0FH | AL=05H | | 实验3 | AL=55H | OR 0F0H | AL=F5H | ## 七、思考题 ### 7.1 基础性实验思考题 #### 思考题一:在数据传送指令中,MOV指令和XCHG指令有什么区别? **答**: - MOV指令:将源操作数的数据传送到目的操作数,执行后源操作数内容不变 - XCHG指令:交换两个操作数的内容,执行后两个操作数的内容互相交换 例如: ``` MOV AL, BL ; 将BL的内容复制到AL,BL内容不变 XCHG AL, BL ; 将AL和BL的内容互换 ``` #### 思考题二:在多字节加法运算中,为什么要使用ADC指令而不是ADD指令? **答**: 在多字节(多字)加法运算中,低位相加可能产生进位。如果低位用ADD指令,高位必须用ADC(Add with Carry)指令来加上低位产生的进位,否则会丢失数据。 例如32位加法: - `ADD AX, CX` 计算低16位,可能产生CF(进位标志) - `ADC DX, BX` 计算高16位,同时加上低位产生的进位 #### 思考题三:拆字程序中,SHR指令的作用是什么?还有什么方法可以实现拆字? **答**: SHR(Shift Right)指令将目的操作数右移指定的位数。本程序中`SHR AH, CL`将AH右移8位,相当于把AH的高8位移到低8位,原高8位变为0,从而得到高8位数据。 其他拆字方法: 1. 使用MASK操作:`MOV BH, AH AND 0F0H`,然后右移4位 2. 使用`MOV BH, AH`和`AND BH, 0F0H` 3. 使用`ROL AX, 8`将高8位旋转到低8位 ### 7.2 加强性实验思考题 #### 思考题一:MUL指令执行后,结果放在哪里?什么时候需要扩展被乘数? **答**: - 8位×8位乘法:结果放在AX(16位) - 16位×16位乘法:结果放在DX:AX(32位) - 32位×32位乘法:结果放在EDX:EAX(64位) 当被乘数放在AL/AX/EAX时,需要扩展到高8/16/32位: - 被乘数是字节时,隐含在AL中,高8位为0 - 被乘数是字时,隐含在AX中,高16位为0 - 被乘数是双字时,隐含在EAX中,高32位为0 如果被乘数不是0扩展,需要先将高位清零或设置正确的值。 #### 思考题二:SUB指令和CMP指令有什么区别? **答**: - SUB指令:执行减法并存储结果,修改目的操作数 - CMP指令:执行减法但不存储结果,只影响标志位 CMP指令通常与条件跳转指令配合使用,根据标志位判断条件。 例如: ``` CMP AX, BX ; AX - BX,不存储结果,只设置标志位 JE EQUAL ; 如果相等(ZF=1)则跳转 ``` #### 思考题三:AND指令和OR指令在执行时有什么特点?它们如何影响标志位? **答**: AND和OR都是逻辑运算指令: **AND指令特点**: - 任何位与1相与保持不变 - 任何位与0相与结果为0 - 常用于清零特定位(掩码操作) - 影响OF=0,CF=0,SF/ZF/PF根据结果设置 **OR指令特点**: - 任何位与0相或保持不变 - 任何位与1相或结果为1 - 常用于置1特定位 - 影响OF=0,CF=0,SF/ZF/PF根据结果设置 例如: - `AND AL, 0FH` 将AL的高4位清零,低4位保留 - `OR AL, 80H` 将AL的最高位置1 ## 八、实验心得 1. 通过本次实验,深刻理解了数据传送指令MOV和算术运算指令ADD、SUB、MUL的使用方法。 2. 顺序程序是最基本的程序结构,按照指令顺序依次执行,理解了其执行流程。 3. 多字节加法运算需要考虑进位问题,正确使用ADC指令是实现32位以上加法的关键。 4. 拆字程序展示了移位指令SHR的应用,通过移位可以方便地分离高位和低位数据。 5. 乘法指令MUL的执行结果自动存放在AX或DX:AX中,需要根据结果大小使用相应的寄存器。 6. 逻辑运算指令AND和OR可以用于位操作,实现掩码和置位功能。 7. 通过实验掌握了DEBUG的使用方法,为后续复杂的汇编程序调试打下基础。