汇编Lab1:排除语法错误
# 南邮汇编实验一:1. 汇编语法——排除语法错误
实验名称 汇编语言语法实验——排除语法错误 实验人员 季嘉澎 指导老师 闵丽娟 指导单位 南京邮电大学物联网学院 实验性质 验证 实验时间 2020-09-24 09:35 实验课时 2 课程名称 微型计算机与接口技术【B1801522S】 参考教材 微型计算机原理与接口技术实验指导(第二版)【978-7-302-42201-3】page 8
# 实验目的和要求
进一步学习汇编语言程序的编辑、汇编、目标文件的链接和可执行文件的执行全过程;掌握编辑软件、MASM、LINK 和 Debug 的使用方法;掌握汇编语言的语法规则。
# 实验环境
- 实验环境:(DOSbox v0.74)
- 编程语言:工作于80x86微处理器的Intel风格汇编语言
- 实验工具:MASM32 SDK v5.0 (opens new window)
INTRODOCTION
The Microsoft Assembler (commonly known as MASM) is an industrial software development tool that has been maintained and updated for over 30 years by a major operating system vendor. It has never been softened or compromised into a conSUMer friendly tool and is designed to be used by professional programmers for operating system level code and high performance object modules, executable files and dynamic link libraries.
The MASM32 SDK is an independent project that is designed to ease the entry of experienced programmers into the field of assembler language programming. It is a complex and demanding form of programming that requires high coding precision and a good understanding of both the Intel mnemonics and x86 processor architecture as it is utilised by the Windows operating system environment but for the effort, it offers flexibility and performance that is beyond the best of compilers when a high enough level of expertise is reached.
# 实验项目
排除语法错误:下面给出的是一个通过比较完成8位二进制数转换成十进制数送屏幕显示功能的汇编语言源程序,但有很多语法错误。要求实验者按照原样对源程序进行编辑,汇编后,根据MASM给出的错误信息对源程序进行修改,直到没有语法错误为止。然后进行链接,并执行相应的可执行文件。正确的执行结果是在屏幕上显示25+9=34
。
;FILENAME: EXA131.ASM
.486
DATA SEGME NT USE16
SUM DB ?,?,
MESG DB '25+9='
DB 0,0
N1 DB 9,F0H
N2 DW 25
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX, DATA;
MOV DS, AX;
MOV BX, OFFSET SUM
MOV AH, N1
MOV AL, N2
ADD AH, AL
MOV [BX], AH
CALL CHANG
MOV AH, 9
MOV DX, OFFSET MEST
INT 21H
MOV AH, 4CH
INT 21H
CHANG: PROC
LAST: CMP [BX], 10
JC NEXT
SUB [BX], 10
INC [BX+7]
JMP LAST
NEXT: ADD [BX+8], SUM
ADD [BX+7], 30H
ADD [BX+8], 30H
RET
CHANG: ENDP
CODE: ENDS
END BEG
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
说明
汇编语言里面规定:
- 符号关键字不能以数字开头,只能是字母或者下划线
- 而用十六进制表示立即数时,开头不能是字母,必须加上0,如
0FFBH
- 所以上述第8行的
F0H
是为了提醒将符号关键字与十六进制立即数区分开来
# 修改方案
通过已经学习过的汇编语言80x86指令集和汇编语言程序设计,上面被高亮的代码是存疑的代码段,代码片段后增加了注释说明
;FILENAME EXA121.ASM
;.486 ;masm5.0 不兼容80486标识
DATA SEGMENT ;USE16 ;SEGMENT段定义(怀疑是印刷错误);masm5.0 不兼容80486标识
SUM DB ?,? ;去掉最后的','
MESG DB '25+9=',
DB 0,0,'$' ;此处定义了将被【09H】DOS功能调用——显示字符串 的输出字符序列,应在最后添加'$'字符(24H)来标志字符串结束
N1 DB 9 ;F0H多余的定义
N2 DW 25 ;DW定义25占用两个字节,但下面代码原本都是将其当做单字节内存数,可以改成DB或者在下面的运算中对所有的N2使用 BYTE PTR
DATA ENDS
CODE SEGMENT ;USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX, DATA
MOV DS, AX
MOV BX, OFFSET SUM
MOV AH, N1
MOV AL, byte PTR N2 ;使双操作数等长
ADD AH, AL
MOV [BX],AH
CALL CHANG
MOV AH,9
MOV DX, OFFSET MESG
INT 21H
MOV AH, 4CH
INT 21H
CHANG PROC ;子程序定义不需要 ':'
LAST:
CMP byte PTR [BX],10 ;双操作数至少要知道一个操作对象的长度,并等长
JC NEXT
SUB byte PTR [BX],10 ;PTR 指定内存数为单字节
INC byte PTR [BX+7] ;增加十位,并指定内存数为单字节
JMP LAST
NEXT: MOV AH, SUM
ADD [BX+8], AH
ADD byte PTR [BX+7],30H ;十位数转为 ASCII 码,并指定内存长度为单字节
ADD byte PTR [BX+8],30H ;个位数转为 ASCII 码,并指定内存长度为单字节
RET
CHANG ENDP
CODE ENDS
END BEG
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# 其它方案
是否可以修改原代码中第 7 行将 DB 0,0
改为只定义 1 个 0
分析:
原方案的思路是将求得的和放在
SUM
中,然后通过比较法完成 8 位二进制数转换成十进制数,并分别把十位和各位存放在SUM+7
和SUM+8
中不难发现在
SUM
后还有一个空置的字节,因此可以将求得的和放在SUM+8
中,把通过比较法完成 8 位二进制数转换成十进制数的十位和各位存放在SUM
和SUM+1
中在输出时,先输出
25+9=
字符串,然后分别使用 【02H】DOS功能调用把SUM
中的十位、SUM+1
中的个位以字符串输出
代码如下:
;FILENAME EXA121.ASM
DATA SEGMENT
SUM DB ?,? ;用来存放和的十位和个位
MESG DB '25+9=','$'
DB 0 ;用来存放求得和
N1 DB 9
N2 DW 25
DATA ENDS
CODE SEGMENT ;USE16
ASSUME CS:CODE,DS:DATA
BEG:
MOV AX, DATA
MOV DS, AX
MOV BX, OFFSET SUM
MOV AH, N1
MOV AL, byte PTR N2
ADD AH, AL
MOV [BX+8],AH
;CALL CHANG ;先输出 '25+9='再进入子程序
MOV AH,9
MOV DX, OFFSET MESG
INT 21H
CALL CHANG
MOV AH, 4CH ;结束子程序运行,返回DOS
INT 21H
CHANG PROC
LAST:
CMP byte PTR [BX+8],10
JC NEXT
SUB byte PTR [BX+8],10
INC SUM
JMP LAST
NEXT:
MOV CH, [BX+8]
MOV SUM+1, CH
ADD SUM,30H
MOV DL,SUM
MOV AH,02H ;打印出十位
INT 21H
ADD SUM+1,30H
MOV DL,SUM+1
MOV AH,02H ;打印出个位
INT 21H
RET
CHANG ENDP
CODE ENDS
END BEG
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 运行结果
有勘误或者讨论,欢迎在评论留言,或者邮箱联系我 (づ ̄ 3 ̄)づ