汇编入门笔记(四)

3.字单元

注意区别字和字节:

image-20210926170323996

4.DS 和 [address]

DS寄存器:通常用来存放要访问数据的段地址。

[address]表示一个偏移地址为address的内存单元,段地址默认放在ds中。

通过数据段段地址偏移地址即可定位内存单元。(CPU会根据这两个地址信息自动定位)

8086CPU不支持直接将数据送入段寄存器,必须借助通用寄存器(AX,BX等)将数据送到段寄存器DS。(数据—>通用寄存器—>段寄存器)

1
2
3
4
5
6
7
mov bx, 1000H ;8086CPU不支持将数据直接送入段寄存器的操作
mov ds, bx ;ds存放数据段地址
mov [0], al ;将al数据(1字节)存到1000H段的0偏移地址处,即10000H:0

mov ax, [2] ;将数据段偏移地址2处的一个字(8086为2字节)存放到ax寄存器
add cx, [4] ;将偏移地址4处的一个字数据加上cx寄存器数据放到cx寄存器
sub dx, [6] ;dx寄存器数据减去数据段偏移地址6处的字数据存到dx

5.字的传送

image-20210926193302939

可以通过16位寄存器传送一个字(1字 = 2字节)。

注意:mov ax,[0],送的是字数据,所以将ds:1ds:0的一整个字送入16位寄存器ax

小练习:

image-20210926194947767

这些命令都在实验(一)中用过。

使用debug的e命令以十六进制形式改写内存内容。

e 1000:0 23 11 22 66

然后输入对应指令,一条一条执行,验证结果。

image-20210926195014456

0x07:mov、add、sub 指令

image-20210926200300261

实际上,经过debug验证,mov 寄存器,段寄存器mov 段寄存器,[内存单元]这样的mov指令也是存在的。

image-20210926201134944

0x08:栈

补充:一个汇编学习软件(文档): F:\下载\Compressed\emu8086\汇编金手指\huibianjsz

栈的特点:FIFO。

和数据结构中的栈类似,稍有区别。

基于8086CPU编程,我们可以将一段内存当作栈来使用。

==栈段寄存器SS,存放段地址,SP寄存器存放偏移地址,任意时刻,SS:SP指向栈顶元素。==

8086CPU中,入栈时,栈顶从高地址向低地址方向增长。

push ax表示将寄存器ax中的数据送入栈中,由两步完成。

注意:栈的操作以字为单位!!!

image-20210926203015660

pop ax表示从栈顶取出数据送入ax,由以下两步完成。

  1. 将SS:SP指向的内存单元处的数据送入ax中;
  2. SP=SP+2,SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元为新的栈顶。

push和pop每次移动一个字。(1字 = 2字节)

image-20210926203913032

栈顶越界的问题:上溢或下溢。

8086并不能处理这个问题,需要程序员自己注意。

小练习:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mov ax, 1000H 
mov ss, ax
mov sp, 0010H ;初始化栈顶
mov ax, 001AH
mov bx, 001BH
push ax
push bx ;ax、bx入栈

sub ax, ax ;将ax清零,也可以用mov ax,0,
;sub ax,ax的机器码为2个字节,
;mov ax,0的机器码为3个字节。
sub bx, bx
pop bx ;从栈中恢复ax、bx原来的数据
pop ax ;

0x09:第一个汇编程序

image-20210926210519063

使用汇编语言编译程序(MASM.EXE)对源程序编译,产生目标文件;

再用连接程序(LINK.EXE)对目标文件进行连接,生成可在操作系统中直接运行的可执行文件。

可执行文件包含程序和数据,一些描述信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
;1.asm
assume cs:codesg ;将用作代码段的段codesg和段寄存器cs联系起来。

codesg segment ;定义一个段,段的名称为“codesg”,这个段从此开始
;codesg是一个标号,作为一个段的名称,最终被编译连接成一个段的段地址

mov ax, 0123H
mov bx, 0456H
add ax, bx
add ax, ax

mov ax, 4c00H
int 21H ;这两条指令实现程序的返回

codesg ends ;名称为“codesg”的段到此结束

end ;编译器在编译汇编程序的过程中,碰到了伪指令end,结束对源程序的编译

以上程序中不是汇编指令的就是伪指令。

xxx segment和xxx ends是成对出现的伪指令。功能是定义一个段,表示开始,结束。

end伪指令是汇编程序的结束标志,遇到end结束编译。

不要搞混end和ends。

assume伪指令将一个段寄存器和xxx segment与xxx ends定义的段关联起来。

坚持原创技术分享,您的支持将鼓励我继续创作!