![b27992fe6d19f2fcf69ee6ef18e83b5f.png](https://i-blog.csdnimg.cn/blog_migrate/940ce90ecdad9d2a07ab5005f9ab0e09.jpeg)
4.1 数据定义——DB/DW/DD/DQ/DT
格式:[变量名] Mnemonic Oprand,…,Oprand
*操作数(Oprand):指按顺序入存储器中的数据,可以是数值、表达式或符号(需预先定义)
*助记符(Mnemonic):数据类型
DB: 1个字节(1 byte, 8 bits)
DW: 1个字(2 bytes, 16bits)
DD: 2个字(4 bytes, 32bits)
例子
D_BYTE DB 10,4,10H
D_WORD DW 3*20,100H
D_DW DD -5
D_SIGN DW D_DW
![a6cf3387d0bbcdeb8e0aaa9b70befd99.png](https://i-blog.csdnimg.cn/blog_migrate/d2e0c119f4831d36c24000587aee85ac.png)
![9dac83650f89ea7352b470edc2852853.png](https://i-blog.csdnimg.cn/blog_migrate/cf978b2a5105536c46423577b369045a.png)
*DUP(复制操作符)*
eg:array DB 100 DUP(?)
允许DUP操作嵌套
![6276ee9d813da595ed45964ca69e5b2c.png](https://i-blog.csdnimg.cn/blog_migrate/3753da3f2de89ac3bca8933e46d55a29.png)
*操作数?可以保留存储空间,但不存入数据
VAR1 DB AB,?,?,?,CD
VAR2 DW ?,52,?
*注意类型的匹配问题
4.2 地址计数器——$
ü地址计数器:在汇编指令时保存指令的偏移地址;在汇编数据段时,计算变量的偏移地址。
ü
ü$表示当前地址值。
![61a32f5588c5d10d0b118bcbe113fc4f.png](https://i-blog.csdnimg.cn/blog_migrate/20f59324c4501d8d546312cd9af7188f.jpeg)
这里比如第一个是 偏移地址为0004 加4得到0008 存入与图中一样
![9fb29ac42abe19c8ad49e56b37b54c92.png](https://i-blog.csdnimg.cn/blog_migrate/93948e477b7167ccaa550de3fd6a4239.jpeg)
4.3 地址对准操作——EVEN/ALIGN
EVEN
üEVEN操作使下一个变量或指令开始于偶数字节地址.
ü一个字的地址最好从偶地址开始,所以对于字数组为保证其从偶地址开始,可以在其前用EVEN伪操作来达到这一目的。
ALIGN
![c0f3596903bac4952f65edb27359cda8.png](https://i-blog.csdnimg.cn/blog_migrate/b86ca7618835295de2c1816c8530735d.jpeg)
4.4 赋值——EQU/=
EQU
![c658c8a300fba5ce9d9df797c57cd89c.png](https://i-blog.csdnimg.cn/blog_migrate/3ffe16b607755e86bbf06509ee90c6d5.jpeg)
![6cfcf441dad2f55d12a0001231c76f82.png](https://i-blog.csdnimg.cn/blog_migrate/8d85559bd4b01adf86478162f791bca4.jpeg)
=
![26e56d743f05f8c35c471963a81fa2a2.png](https://i-blog.csdnimg.cn/blog_migrate/00be401844db6246df8f3d8d00c8b8e1.jpeg)
4.5 段定义伪操作——SEGMENT/ENDS
4.6 程序返回——RET/INT 21H
4.7 符号——三种情况
ü一:符号为变量,编译器编译为[地址]形式
例:
MY_VALUE DW 20A3H
…
MOVAH, MY_VALUE
ü二:符号为标号,通常用于表示代码的某个位置(偏移地址),编译后表现为一个常数,这个常数表示该标号对应的代码所在的有效地址(偏移地址)
例:
NEXT:
MOV AX, 20A3H
MOV BX,NEXT
![d39e9f739685bc3771ef8c1a6b32e738.png](https://i-blog.csdnimg.cn/blog_migrate/6b8c6fdd74b1e70eb06acb930f79b466.png)
ü三:符号为常量表达式,本质是一个常量
更新
;输出字符在屏幕上面
mov dl,"0"
mov ah,02H
int 21H
;比较字符串
mov bx,offset OLDS
mov cx,5
s: mov al,[bx]
mov ah,[bx+5]
cmp al,ah
ja L1 ;
jb L2
inc bx
loop s
MOV AX,BX
不允许用CS寄存器和IP寄存器为目的
不允许两个段寄存器之间直接传送数据
不允许对段寄存器送立即数
8086CPU有4个段寄存器:CS、DS、SS、ES
CS(代码段)、DS(数据段)、SS(堆栈段)、ES(附加段)
AX、BX、CX、DX通常用来存放一般性数据,被称为通用寄存器
IP(指令指针寄存器)
修改CS、IP的指令
- mov指令(传送指令) 可以改变8086CPU大部分寄存器的值,但不能用于设置CS、IP的值。
- jmp指令(转移指令) 可以用来同时修改CS和IP的值,格式为
jmp 段地址:偏移地址;同时修改CS和IP
jmp 某一合法寄存器;则是仅修改IP
数据 -> 通用寄存器 -> 段寄存器
段寄存器SS存放栈顶的段地址,寄存器SP存放栈顶的偏移地址。任意时刻SS:SP指向栈顶元素。push时SP先自减法后写内存,pop先读内存sp后自加。
指令的格式是loop 标号。CUP执行loop指令时要进两步操作:
- CX中存放循环的次数,执行时CX中的内容自减1。相当于C的do while
- 判断CX中的值,不为0则转至标号处执行程序,为0则向下执行。
- 可用and指令将操作对象的相应位设为0,其他位不变
and al,10111111B;将al第六位设为0
and al,01111111B;将al第七位设为0
and al,11111110B;将al第0位设为0
- 可用or指令将操作对象的相应位设为1,其他位不变
and al,01000000B;将al第六位设为1
and al,10000000B;将al第七位设为1
and al,00000001B;将al第0位设为1
在[]中,组合只能以这四种形式:bx和si、bx和di、bp和si、bp和di
![b3f34d8b7baf4befe99db7e5d4b2c84c.png](https://i-blog.csdnimg.cn/blog_migrate/6e0dab2b50d9c25499d6a961234e66cd.jpeg)
更新
call 指令
调用子程序
call name
name proc
。。。
name endp
例:求三个数的最大值(利用call调用)
data segment
buf db 53h,0a9h,89h
ends
......
code segment
start:
......
;代码段
lea bx,buf
mov ah,[bx]
mov al,[bx+1]
call max
mov al,[bx+2]
call max
ends
;子程序
max proc
cmp ah,al
ja L1
mov ah,al
L1:
ret
max endp