例如:编写一个汇编程序实现:x=4,y=5,z=((x+y)*8-x)/2,计算出z的结果。
思路
DATA SEGMENT ;数据段定义伪指令
X DW 4 ;定义X为字单元,值为4
Y DW 5
Z DW ? ;定义Z为空单元
DATA ENDS ;数据段结束
CODE SEGMENT ;代码段定义伪指令
ASSUME CS:CODE,DS:DATA ;指定段寄存器与对应段名
START:MOV AX,DATA
MOV DS,AX ;将数据段段地址送入DS
MOV BX, X
MOV AX, Y
ADD AX,BX ;加法
MOV CL,3
SAL AX,CL ;算术左移3次,相当于乘以8
SUB AX,X ; 减法
SAR AX,1 ; 算术右移1次,相当于除以2
MOV AH,4CH ; 此两句为结束程序,返回DOS
INT 21H
CODE ENDS ; 代码段结束
END START ; 整个程序结束伪指令
如果不指出定位类型,系统默认为PARA。
组合类型:
如果不指定组合类型,系统默认为PRIVATE。
在引号中给出段的类型名,在连接时,类别标识相同的段放在连续的存储区中。例如,用‘STACK’来标识该段为堆栈段 。
ASSUME伪指令用于指明段寄存器与段的对应关系,格式为:
ASSUME段寄存器:段名,[段寄存器:段名,…]
如果不使用ASSUME伪指令,系统就无法获知用户定义的段都有哪些,进而就不能正确地划分段。
存储单元名 [定义] 操作数
确定存储单元的内容时要与存储单元的属性一致。
在实际的存储器中,符号地址(即变量名)已经不存在了,换之以偏移地址,而且最先定义的单元的偏移地址为0000H。此例中,X单元的偏移地0000H,E_1单元的偏移地址为0001H,其他类推。
1.赋值伪指令
在程序中多次出现同一个表达式或者同一个数据时,可以用EQU定义-个符号来代表表达式,以简化书写。与EQU伪操作相似,等号“=”伪操作也可以给表达式赋值,且允许对一个符号多次重复定义。而EQU则不允许重复定义。
第一种格式中,expression 必须是一个有效整数表达式。第二种格式中,symbol 是一个已存在的符号名称,已经用 = 或 EQU 定义过了。第三种格式中,任何文本都可以岀现在<…>内。当汇编器在程序后面遇到 name 时,它就用整数值或文本来代替符号。
2.模块定义伪指令
在汇编语言中,可以将程序设为多个模块,每个模块完成独立的功能,整个程序可以用LINK连接到一起。因此,每个模块可用模块定义伪指令定义名称和结束标识。格式为:
[NAME模块名]
…
END 启示标号
其中,NAME伪指令可以缺省。如果缺省,则以该模块的源程序名作为模块名。END 伪指令不能缺省,其后的起始标号可以是程序的第-条汇编指令的标号START,或者是主过程名。它们用来指出程序的起始地址,也是对代码段寄存器CS初始化的依据。
3.地址计数器$
地址计数器$表示当前的偏移地址值。
如果在数据段的存储单元定义中使用,可写成:
ABC DW 1,2,$+3,4
如果用在转移指令中:
JMP $+5
则无条件跳转到当前指令的偏移地址+5单元继续执行。
4.设置偏移地址伪指令
当前的偏移地址可以用ORG伪指令定义。
如果用在数据段中,该指令可以确定存储单元的偏移地址。例如,将X单元的偏移地址定义为0020H,该单元的内容为5,即(DS: 0020H) =5。伪指令如下:
DATA SEGMENT
ORG 0020H
X DW 5
DATA ENDS
如果用在代码段中,可从指定的单元开始存放并执行指令。例如,从代码段的100H开始执行:
ORG 100H
SIGN:MOV AX,X ;标号SIGN被设置为100H
MOV BX,Y
ADD AX,BX
5.操作符
在汇编指令中可以使用–些操作符,汇编程序汇编时将这些操作符变为相应的数值回送或者定义属性.
DOS功能调用
常用的DOS功能有5个:
- 1号功能键盘输入
格式:
AH=1
INT 21H
从键盘输入一个字符并将该字符的ASCⅡ码送入AL中
- 2号功能显示器输出
格式:
AH=2
DL=字符
INT 21H
输出DL中的一个字符到显示器的光标处。
例如:键盘输入的大写字母换成小写字母显示
CODE SEGMENT
ASSUME CS:CODE ;段寄存器的说明语句,定义code为代码段
START:
MOV AH,1 ;输入
INT 21H
SUB AL,32 ;转换
MOV DL,AL
MOV AH,2
INT 21H
MOV AH,4CH
INT 21H ;结束程序返回DOS
CODE ENDS
END START
键盘输入字符串
格式:
AH=10
DS:DX=字节缓冲区首址
INT 21H
定义缓冲区的第1个字节单元为允许输入的最大字符数,第2个单元为实际键入个数(由系统自动填入),从第3个单元开始存放键入字符。从键盘输入一串ASCII字符到缓冲区,用“回车”结束输入。若输入字符超过缓冲区能容纳的个数,则系统忽略此字符并响铃警告。
显示字符串
格式:
AH=9
DS:DX=字符串地址
INT 21H
显示一个以$结尾的字符串,执行后AL寄存器被修改为 $ 的ASCLL码24H
例如:显示出两个字符串:
data segment
mess1 db 'input x :','$' ;$字符串结束符
mess2 db 0ah,0dh,'out put','$' ;0ah,0dh,换行回车
data ends
code segment
assume cs:code,ds:data
start : mov ax,data ;将伪段地址放入ax中
mov ds,ax ;就是将段地址装入段寄存器
mov dx,offset mess1 ;回送偏移地址
mov ah,9
int 21h
mov dx,offset mess2
mov ah,9
int 21h
mov ah,4ch
int 21h
code ends
end start
参考书籍:《汇编语言》第二版 郑晓薇
下篇重点总结各种基本汇编指令,链接。