微机原理笔记(5)
2024-01-08 03:55:39
一、汇编语言程序的基本结构
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
二、常用伪指令
1、数据定义伪指令?
- 用途:是定义一个变量的类型,给变量赋初值,或仅仅给变量分配存储单元。
- 有:DB、DW、DD、DF、DQ、DT
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个字节 |
2、符号定义伪指令
- 常用的有:EQU、=(符号)和LABLE。
- EQU伪指令将表达式的值赋予一个名字,以后可用这个名字来代替上述表达式
3、段定义伪指令
- ?用途:在汇编语言源程序中定义逻辑段。常用的段定义伪指令有SEGMENT/ENDS和ASSUME等。
(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?
4、操作数伪操作
(1)算术操作符
- 算术操作符有+、-、*、/和MOD。MOD是指整除运算后取余数
(2)逻辑与位移操作符
- 逻辑操作符有AND、OR、XOR、NOT,位移操作符有SHL和SHR?
(3)关系操作符
- 关系操作符SQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于或等于)、GE(大于或等于)。运算结果是逻辑值真或假。真用OFFFFH表示,假用0表示。
(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:回送变量或标号的段地址。
5、属性操作符?
(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寄存器中。
?6、过程定义伪指令
- 过程也就是子程序,所以过程定义伪指令也就是子程序定义伪指令。
- 格式:
过程名 PROC [NEAR/FAR]
? ? ? ? ...
? ? ?RET
过程名 ENDP - 调用一个过程的格式为:
? ? ?CALL 过程名 - 过程名实质上是过程入口的符号地址,它和标号一样,也有段。偏移地址和类型三种属性
三、DOS功能调用(掌握)
常用的DOS系统功能调用:
1.单字符调用(1号调用)
- 格式:MOV AH,1
? ? ? ? ??INT 21H- 功能:从键盘输入字符的ASCII码送入寄存器AL中,并送显示器显示。
2、单字符显示(2号调用)
- 格式:MOV DL,待显示字符的ASCII码
? ? ? ? ? MOV AH,2
? ? ? ? ? INT 21H- 功能:将DL寄存器中的字符送显示器显示,如果DL中为<CTRL>+<BREAK>的ASCII码,则退出。
3、打印输出(5号调用)
- 格式:MOV DL,待打印字符的ASCII码
? ? ? ? ? MOV AH,5
? ? ? ? ? INT21H- 功能:将DL寄存器中的字符送入打印机打印。
4、结束调用(4CH号调用)
- 格式:MOV AH,4CH
? ? ? ? ? INT 21H- 功能:终止当前程序并返回调用程序
5、显示字符串(9号调用)
- 格式:LEA DX,待显示字符串首偏移地址
? ? ? ? ? MOV AH,9
? ? ? ? ? INT 21H- 功能:将当前数据区中以‘$’结尾的字符串送显示器显示
6、字符串输入(10号调用)
?格式:LEA DX,缓冲区首偏移地址
? ? ? ? ? ?MOV AH,10
? ? ? ? ? ?INT 21H功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示区显示。
四、三种结构
程序有顺序、循环、分支和子程序四种结构形式
1、顺序程序结构
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
2、分支程序设计
CMP AX,0
JGE DONE ;如果(AX)大于等于0,则转到DONE
NEG AX ;否则进行求补运算
DONE:MOV RESULT,AX ;保存结果
设计分支程序:首先要产生条件,然后对条件进行分析判断,然后决定去执行哪一个分支。其中产生条件的指令通常由指令系统中影响状态标志位的指令来产生,比如:算术运算命令(ADD、SUB、CMP)、逻辑运算指令(AND、TEST),移位指令(SHR,SHL)。?
- ?例题:X大于0时Y输出1,等于0时Y输出0,否则1.
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
3、循环结构?
- ?按结构可分单重循环和多重循环,按循环控制可分计数型循环与条件型循环。
- 由四部分组成:
- 循环初始化部分
- 工作部分(循环体)
- 修改部分
- 循环控制部分
- 例子:已知有n个8位有符号二进制数,存放在以BUF为首址的字节存储区中,试统计其中正数的个数。?
- 分析:每个元素是一个8位有符号二进制数,因此要判断其是否为正数,需要选择带符号数条件转移指令进行判断转移。由于共有n个元素,因此整个程序的结构就是对以上判断重复n次,选用计数型循环程序实现。
- 存储单元以及寄存器分配如下:
BX:BUF存储区的地址指针,初值为BUF的偏移地址,每循环一次之后,其值加1
CX:循环计数器,初值为BUF存储区中元素的个数n,每循环一次之后,其值减1
AX:用来存放正数的个数,初值为零
字变量COUNT:用来最终存放正数的个数。
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
?
?
文章来源:https://blog.csdn.net/lerp020321/article/details/135314565
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!