data segment ;定义数据段
a db ? ;定义变量
b db ?
c db ?
string db 'c=$'
data ends
code segment ;定义代码段
main proc far ;主程序从此开始
assume cs:code, ds:data, es:data
start:
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
;数据段的地址装入专用寄存器
mov es,ax
mov a,1 ;给变量赋值
mov b,2
mov a1,a
add a1,b ;a+b
mov c,a1 ;运算结果存入c变量中
lea dx,string
mov ah,09
int 21h ;输出字符串
add c,30h
;整数转化为字符,因为汇编输出的都是字符
mov d1,c
mov ah,2
int 21h
;输出d1中字符,这是21号中断的功能调用
mov d1,0ah
int 21h ;换行
mov d1,0dh
int 21h ;回车
ret
main endp
code ends
end star1
FILLER? DB? ? | 给字节变量FILLER分配存储单元。但不赋予特定的值 |
BUFFER? DB? 10? DUP(?) | 给变量BUFFER分配10个字节的存储空间,但不赋予任何初值 |
ZERO? DW? 30 DUP(0) | 给变量ZERO分配一个数据区,共30个字(即60字节),每个字的内容均为零 |
MASK? DB? 5? DUP('OK!') | 定义一个数据区,其中有5个重复的字符串'OK!' |
ARRAY? DB? 100? DUP(3? DUP(8),6) | 将变量ARRAY定义为一个数据区,其中包含重复100次的内容:8,8,8,6,共占400个字节 |
(1)SEGMENT/ENDS
- 格式:SEGMENT [定位类型][组合类型][‘类别’]?
? ? ? ? ? ? ? ? ...
? ? ? ? ? ?段名 ENDS(2)ASSUME
- 格式:ASSUME 段寄存器名:段名 [,段寄存器名:段名,...]
例子:
CODE? ? ? ? SEGMENT
? ? ? ? ASSUME CS:CODE,DS:DATA1,SS:STACK
? ? ? ? MOV? ? ? ? AX,DATA1
? ? ? ? MOV DX,AX? ? ? ? ;给DS赋值
? ? ? ? MOV AX,STACK
? ? ? ? MOV SS,AX? ? ? ? ;给SS赋值CODE? ? ? ? ENDS?
(1)算术操作符
(2)逻辑与位移操作符
(3)关系操作符
(4)数值回送操作符
这些操作符把一些特征值或存储器地址的一部分作为结果回送。
- (1)TYPE:返回变量的字节数,如果变量为DB格式定义的,则返回1;若以DW定义,则返回2;DD为4,DQ为8,DT为10。
- (2)LENGTH:对于数据段中定义变量时使用DUP的情况,汇编程序回送分配给该变量的单元数,对于其他情况则回送1。
- (3)SIZE:回送分配给变量的字节数,它等于LENGTH与TYPE的乘积?。
- (4)OFFSET:回送变量或标号的偏移地址。
? ? ? 例:mov bx,offset s1;汇编程序将变量s1在数据段中的偏移地址回送给BX,等价于LEA BX,S1。- (5)SEG:回送变量或标号的段地址。
(1)PTR
- 格式:type PTR expre,用于建立一个符号地址,给已分配的存储地址赋予另一个属性,是该地址具有另一种属性
- 例子:
? 在数据段定义a db 1
? 在代码段有MOV AX,WORD PTR a;则汇编程序把变量a中的数据以word形式装入AX寄存器。(2)段跨越前缀
- 用来指定段名称,在计算地址时使用指定的段地址和偏移地址而不是使用默认的段地址
- 例如指令:MOV AX,ES:[BX+SI]。把附加段中偏移地址为BX+SI的存储单元中的数据放入AX寄存器中。
常用的DOS系统功能调用:
- 格式:MOV AH,1
? ? ? ? ??INT 21H- 功能:从键盘输入字符的ASCII码送入寄存器AL中,并送显示器显示。
- 格式:MOV DL,待显示字符的ASCII码
? ? ? ? ? MOV AH,2
? ? ? ? ? INT 21H- 功能:将DL寄存器中的字符送显示器显示,如果DL中为<CTRL>+<BREAK>的ASCII码,则退出。
- 格式:MOV DL,待打印字符的ASCII码
? ? ? ? ? MOV AH,5
? ? ? ? ? INT21H- 功能:将DL寄存器中的字符送入打印机打印。
- 格式:MOV AH,4CH
? ? ? ? ? INT 21H- 功能:终止当前程序并返回调用程序
- 格式:LEA DX,待显示字符串首偏移地址
? ? ? ? ? MOV AH,9
? ? ? ? ? INT 21H- 功能:将当前数据区中以‘$’结尾的字符串送显示器显示
?格式:LEA DX,缓冲区首偏移地址
? ? ? ? ? ?MOV AH,10
? ? ? ? ? ?INT 21H功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示区显示。
程序有顺序、循环、分支和子程序四种结构形式
STACK SEGMENT STACK
DB 200 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:STACK
BEGIN:MOV BX,00F8H
MOV AX,BX ;将原始数据保存在AX中
MOV CL,3 ;CL中存放移位次数3
SHL BX,CL ;算术左移3次,即(BX)*8-->(BX)
ADD BX,AX
ADD BX,AX
MOV AH,4CH
INT 21H;
CODE ENDS
END BEGIN
执行程序后,(BX)=09B0H
CMP AX,0
JGE DONE ;如果(AX)大于等于0,则转到DONE
NEG AX ;否则进行求补运算
DONE:MOV RESULT,AX ;保存结果
设计分支程序:首先要产生条件,然后对条件进行分析判断,然后决定去执行哪一个分支。其中产生条件的指令通常由指令系统中影响状态标志位的指令来产生,比如:算术运算命令(ADD、SUB、CMP)、逻辑运算指令(AND、TEST),移位指令(SHR,SHL)。?
DATA SEGMENT
X DB -10
Y DB ?
DATA ENDS
STACK SEGMENT stack
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START:MOV AX,DATA
MOV DS,AX
CMP X,0 ;与0进行比较
JGE A1 ;X大于等于0转A1
MOV Y,-1 ;X小于0时,-1给Y
JMP EXIT
A1: JG A2 ;X大于0转A2
MOV Y,0 ;X等于0时,0给Y
JMP EXIT
A2: MOV AH,4CH ;X大于0,1给Y
INT 21H
CODE ENDS
END STACK
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DB 8,10,-5,100,-7.25.40
N =$-BUF
COUNT DW ?
DATA ENDS
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN: MOV AX,DATA
MOV DS,AX
LEA BX,BUF
MOV CX,N ;循环初始部分
MOV AX,0
AGAIN: CMP BYTE PTR[BX],0
JIE NEXT
INC AX ;循环体部分
NEXT: INC BX
DEC CX
JNZ AGAIN ;控制部分
MOV COUNT,AX ;将正数个数送入COUNT中
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN
?
?