汇编语言程序设计必读
一.汇编语言程序书写格式
方法一:(在程序代码指令部分,同时出现如下两条指令)
MOV AH, 4CH
INT 21H
方法二:将整个程序设计成子程序结束格式
;数据段定义部分
CODE SEGMENT ;代码段部分
MAIN PROC FAR ;主程序开始
ASSUME CS:CODE,DS:DATA
START:PUSH DS
XOR AX, AX
PUSH AX
………… ;(程序指令代码部分)
RET ;程序结束返回语句
MAIN ENDP ;主程序结束
CODE ENDS ;代码段结束
END START
二.汇编语言程序简易书写格式
(1)格式1
.MODEL SMALL ;定义存储模式,采用段简化定义
.STACK 100H ;定义堆栈STACK空间为100H (B),默认1KB。
.DATA
;数据定义部分
.CODE ;定义代码段
MAIN PROC FAR
START:MOV AX,@DATA
MOV DS,AX
………………;指令代码部分
MOV AH,4CH
INT 21H
MAIN ENDP
END START
(2)格式2
.MODEL SMALL ;定义存储模式,采用段简化定义
.STACK 100H
.DATA
;数据定义部分
.CODE ;定义代码段
MAIN PROC FAR
START:PUSH DS
XOR AX,AX
PUSH AX
MOV AX,@DATA ;装填数据段DS段基
MOV DS,AX
……………… ;指令代码部分
RET ;利用子程序返回的方法
MAIN ENDP
END START
(3)上机实例:上机程序清单程序文件名 exampl2.asm
.MODEL SMALL ;定义存储模式,采用段简化定义方式
.STACK 100H
.DATA
A DB ‘I am a student.$‘ ;数据定义部分
.CODE ;定义代码段
MAIN PROC FAR
START:MOV AX,@DATA
MOV DS,AX
LEA DX,A ;屏幕输出字符串A的内容
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
END START
该程序汇编、连接运行,屏幕显示结果:I am a student.
3. 汇编语言程序规范书写格式
(1)规范格式1
数据段名 SEGMENT [定位类型] [组合类型] [使用类型] [类别]
;分别用DB、DW、DD等可分配空间的为伪指令定义变量
数据段名 ENDS
堆栈段名 SEGMENT [定位类型] STACK [使用类型] [类别]
;定义空间
堆栈段名 ENDS
代码段名 SEGMENT [定位类型] [组合类型] [使用类型] [类别]
ASSUME CS:段码段名,DS:数据段名,SS:堆栈段名,ES:附加数据段名
;上述语句定义寻址关系
START:MOV AX,数据段名 ;装填数据段段基
MOV DS,AX
MOV AX,附加数据段名 ;装填附加数据段段基
MOV ES,AX
………………………… ;程序代码指令部分
MOV AH,4CH ;程序结束退出
INT 21H
代码段名 ENDS
END START
说明:(1)有关[定位类型] [组合类型] [使用类型] [类别] 说明详见教材P120页
(2)上机实例如下:
上机题:编程显示一串字符串“I am a student. “
程序文件名:example3.asm
DATA SEGMENT
A DB ‘I a student.$’
DATA ENDS
STACK SEGMENT
DW 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:MOV AX,DATA
MOV DS,AX
LEA DX,A
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
(2)规范格式2
以上机实例的形式说明上机题:编程显示一串字符串“I am a student.”。 程序文件名:example3.asm,程序清单如下:
DATA SEGMENT
A DB ‘I a student.$’
DATA ENDS
STACK SEGMENT
DW 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
MAIN PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
LEA DX,A
MOV AH,9
INT 21H
RET
MAIN ENDP
CODE ENDS
END MAIN
三.子程序设计
上机程序实例如下,程序清单:example4.asm
DATA SEGMENT
A DB ‘abcd$’
DATA ENDS
CODE SEGMENT ;定义代码段CODE
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
LEA DX, A
MOV AH,9
INT 21H
CALL SUB1 ;调用子程序 SUB1
MOV DL,‘A’
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H
SUB1 PROC NEAR ;子程序SUB1 在代码段CODE内
MOV DL,‘B‘ ;程序运行结果为显示:B
MOV AH,2
INT 21H
RET ;子程序返回
SUB1 ENDP
CODE ENDS ;代码段CODE结束
END START
程序运行结果为:abcdBA
2. 段间调用子程序设计范例 , 程序文件名:example5.asm
(主程序在段code1内,子程序在段code2内)
stack segment stack 'stack' ;定义堆栈段stack
dw 100 dup(?)
stack ends
data1 segment ;定义数据段data1
A db 'abcd$'
data1 ends
code1 segment ;定义代码段code1
assume cs:code1,ds:data1
main proc far ;主程序main
start:push ds
xor ax,ax
push ax
mov ax,data1
mov ds,ax
lea dx,A ;显示字符串A(即abcd)
mov ah,9
int 21h
call far ptr sub1 ;调用子程序 sub1,显示12345
mov dl,'A' ;显示字符A
mov ah,2
int 21h
ret ;主程序结束
main endp
code1 ends ;代码段code1结束
data2 segment ;定义数据段data2(子程序sub1数据段)
B db '12345$'
data2 ends
code2 segment ;定义代码段code2
assume cs:code2,ds:data2
sub1 proc far ;段间(即在段code2中)子程序sub1
mov ax,data2
mov ds,ax
lea dx,B ;显示字符串B(即12345)
mov ah,9
int 21h
ret ;子程序sub1结束
sub1 endp
code2 ends ;段code2结束
end start ;整个程序结束
程序运行结果:abcd12345A
3. 在不同程序文件中调用子程序
主程序文件:main.asm 主程序调用下面3个子程序文件,显示:ABC
子程序1文件: sub1.asm 该程序显示1个字符:A
子程序2:文件 sub2.asm 该程序显示1个字符:B
子程序3:文件 sub3.asm 该程序显示1个字符:C
上机实现如下:
第一步:编写主程序文件main.asm
Extrn sub1:far, sub2:far, sub3:far
Stack segment para stack ‘stack’
Dw 100 dup(?)
Stack ends
Code segment
Assume cs:code, ss:stack
Start:mov ax,stack
Mov ss, ax
Call sub1
Call sub2
Call sub3
Mov ah,4ch
Int 21h
Code ends
End start
存盘,汇编成目标文件: main.obj
第二步:编辑子程序文件1:sub1.asm
Public sub1
Code segment
Sub1 proc far
Assume cs:code
St1:mov dl, ‘A’
Mov ah,2
Int 21h
Ret
Sub1 endp
Code ends
End st1
存盘,汇编成目标文件: sub1.obj
第三步:编辑子程序文件2:sub2.asm
Public sub2
Code segment
Sub2 proc far
Assume cs:code
St2:mov dl, ‘B’
Mov ah,2
Int 21h
Ret
Sub2 endp
Code ends
End st2
存盘,汇编成目标文件: sub2.obj
第四步:编辑子程序文件3:sub3.asm
Public sub3
Code segment
Sub3 proc far
Assume cs:code
St3:mov dl, ‘C’
Mov ah,2
Int 21h
Ret
Sub3 endp
Code ends
End st3
存盘,汇编成目标文件: sub3.obj
第五步:有两种立法可连接生成可执行文件(MAIN.EXE文件)
方法一:
C:\MASM>link main+sub1+sub2+sub3 回车(4次)
运行
C:\MASM>MAIN 回车
屏幕屡示:ABC
方法二:(采用建立子程序库的方法,即使用LIB命令)
操作如下:
第1步:创建子程序库:subm
C:\MASM>LIB 回车
Library name : SUBM 回车
Library does not exist, create? Y 回车
Operations: +sub1+sub2+sub3 回车
List file: subm 回车
第2步:连接生成可执行文件main.exe
C:\MASM>Link main, , , subm 回车
第3步:运行
C:\MASM>MAIN 回车
屏幕显示:ABC
三、宏汇编
1.宏指令的定义格式
宏名 MACRO [参数表] ;(教材参看P246页开始)
指令语句
ENDM
注:(1)宏的定义放在程序的开头,即数据段的定义之前
(2)宏中参数表可缺省,如有多个参数,参数之间用“,”分开。
2、宏指令的调用格式
宏名 [实在参数]
例子:在汇编语言源程序设计中使用“宏的定义与调用”实验例程。
实验1、利用8086宏汇编编程显示任意十进制数(<=32767)的宏定义和调用程序清单
程序清单:
OUTP MACRO X ;红色字体程序段为宏指令名:OUTP 定义部分。
MOV CX, 0 ;该宏的功能是:“二化十”屏幕显示输出。
MOV AX, X
AA1:INC CX
MOV DX, 0
MOV BX,10
DIV BX
PUSH DX
CMP AX,0
JNZ AA1
AA2:POP DX
OR DL, 30H
MOV AH,2
INT 21H
LOOP AA2
ENDM
DATA SEGMENT ;黑色字体部分为主程序部分
A DW 23456
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START :MOV AX, DATA
MOV DS, AX
OUTP A ;调用宠指令 OUTP 参数为A,即显示整数A。
MOV AH,4CH
INT 21H
CODE ENDS
END START
3.[编程实验] 编程计算S=1+2+3+…+100并显示结果
;显示十进制数的宏定义(此处略),即上面 的OUTP 宏定义部分。
;宏定义(照搬上述宏OUTP 定义)
DATA SEGMENT
S DW 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CDOE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV CX,100 ;计算:S=1+2+3+…+100
MOV S,0
MOV AX,1
NEXT:ADD S, AX
INC AX
LOOP NEXT
OUTP S ;调用宏指令OUTP 显示和S。
MOV AH,4CH
INT 21H
CODE ENDS
END START
4、学生动手模仿上述[编程实验],编程完成下列计算并输出结果
(1)计算1~100的奇数和与偶数和. (结果:奇数和2500;偶数和2550)
(2)计算S=1×2+2×3+…+10×11 (结果:440)
(3)计算S=12+22+…+102 (结果:385)
(4)计算S=1!+2!+…+5! (结果:153)
(5)计算S=8! (结果:40320)
注:其实上述宏指令OUTP 可输出0-65535范围内的整数。