目录
《汇编语言》第三章:寄存器(内存访问)
📌 主要内容
本章围绕汇编语言中如何使用寄存器访问内存数据展开,讲解了内存中字的存储方式、段寄存器的默认作用、基本数据传送与运算指令,以及栈的结构与操作。通过程序分析与实验,揭示了 DS:[address] 形式的访问方式和栈操作的底层原理。
重点包括:
- 8086 中字的存储顺序(小端方式);
DS:[address]
表示的含义;MOV
,ADD
,SUB
指令的基本语法与使用;- 栈的结构、操作指令和常见错误(如栈顶越界);
push
和pop
指令的使用场景;- 栈段和段寄存器
SS
,SP
的配合。
🧠 笔记重点
3.1 内存中字的存储
- 一个“字”(word)为 2 字节,低字节在低地址,高字节在高地址 ⇒ 小端存储方式
- 示例:
AX = 1234H
⇒ 内存中为[addr] = 34H
,[addr+1] = 12H
3.2 DS:[address]
的含义
DS
是默认的数据段寄存器;[address]
是段内偏移地址;- 实际访问的物理地址 =
DS × 16 + address
3.3 字的传送
- 16 位数据传送指令示例:
mov ax, [0] mov [2], ax
- 含义:将
DS:0000H
中的字读入 AX,再将 AX 写入DS:0002H
- 含义:将
💡 默认从
DS
指定的段中访问数据
3.4 MOV
、ADD
、SUB
指令
-
MOV
指令用于数据传送,其基本格式为:mov 目标操作数, 源操作数
作用是将源操作数的数据传送到目标操作数。
注意:- 源和目标可以是寄存器、内存单元或立即数;
- 但内存到内存之间不能直接用
MOV
指令传送(必须通过寄存器中转); MOV
指令执行后,源操作数内容不变,目标操作数内容被覆盖。
-
ADD
指令用于执行加法运算,其基本格式为:add 目标操作数, 源操作数
执行效果是:将源操作数的值加到目标操作数上,结果保存在目标操作数中。
注意:- 操作数可以是寄存器或内存;
- 执行后可能改变标志寄存器中的标志位(如零标志 ZF、进位标志 CF)。
-
SUB
指令用于执行减法运算,其基本格式为:sub 目标操作数, 源操作数
执行效果是:用目标操作数减去源操作数,结果保存在目标操作数中。
注意:SUB
会影响标志位(如零标志、借位标志);- 若需要判断两数是否相等,可以通过检查 SUB 后 ZF 标志是否置位。
-
示例程序片段:
mov ax, [0] ; 将内存地址 DS:0000H 处的数据读入 AX add ax, [2] ; 将 DS:0002H 处的数据加到 AX 上 sub ax, [4] ; 将 AX 中的数据减去 DS:0004H 处的数据
说明:
[0]
,[2]
,[4]
是相对于 DS 的偏移地址;- 每条指令执行后,AX 的值会发生变化;
- 操作顺序严格按照程序中指令的先后顺序进行。
-
常见注意事项:
MOV
、ADD
、SUB
操作必须注意操作数的数据位宽一致(比如都为 16 位或都为 8 位);- 若涉及 16 位和 8 位混合操作,需要显式声明;
- 地址操作时必须保证段寄存器(如 DS)正确设置,否则数据来源地址错误。
💡 小结:
MOV
是数据搬运的基础指令,而ADD
与SUB
则是最基本的算术运算指令,三者构成了最基本的数据处理能力,掌握它们是后续编程的基石。
3.5 数据段
- 数据段用于存放变量、数组、常量等数据;
- 使用
DS
寄存器指向数据段; - 可用
ASSUME DS:data
声明默认数据段名。
3.6 栈的基本概念
- 栈是一种先进后出(FILO)结构;
- 通常位于专门的内存区域,由
SS
指定段地址,SP
指定栈顶偏移; - 栈操作由
push
(压栈)与pop
(出栈)指令完成; - 数据入栈时地址减少,出栈时地址增加(栈向下生长)。
3.7 CPU 提供的栈机制
-
push
操作流程:SP ← SP - 2
- 将数据写入
SS:SP
-
pop
操作流程:- 从
SS:SP
读取数据 SP ← SP + 2
- 从
-
示例:
mov ax, 1234h push ax pop bx
3.8 栈顶超界问题
- 栈空间需预留充分,否则压栈过多可能覆盖其他数据;
- 若
SP
初始值设置不当,会造成程序崩溃或数据错乱。
3.9 PUSH
与 POP
指令详解
push reg
:将寄存器内容压入栈;pop reg
:将栈顶内容弹出到寄存器;- 注意:
- 压栈顺序要与出栈顺序对称;
- 不要连续
pop
超过实际push
次数。
3.10 栈段
- 栈段由
SS
指定,需与SP
配合使用; - 示例栈定义与初始化:
assume ss:stack stack segment dw 100 dup(0) ; 定义 100 个字(200 字节)栈空间 stack ends mov ax, stack mov ss, ax mov sp, 200h ; 栈顶从 segment+200h 开始
🧪 实验2:用机器指令和汇编指令编程
- 实验目的:验证
MOV
,PUSH
,POP
, 栈操作与内存访问 - 示例程序:
assume cs:code, ds:data, ss:stack data segment dw 1111h, 2222h, 3333h data ends stack segment dw 100 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 200h mov ax, [0] push ax mov ax, [2] push ax pop bx pop cx mov ax, 4c00h int 21h code ends end start
✅ 检测点 3.1
-
AX=2662H BX=E626H AX=E626H AX=2662H BX=D6E6H AX=FD48H AX=2C14H AX=0000H AX=00E6H BX=0000H BX=0026H AX=000CH
-
mov ax,6622H CS=2000H, IP=3, DS=1000H, AX=6622H, BX=0000H jmp 0ff0:0100 CS=1000H, IP=0, DS=1000H, AX=6622H, BX=0000H mov ax,2000H CS=1000H, IP=3, DS=1000H, AX=2000H, BX=0000H mov ds,ax CS=1000H, IP=5, DS=2000H, AX=2000H, BX=0000H mov ax,[0008] CS=1000H, IP=8, DS=2000H, AX=C389H, BX=0000H mov ax,[0002] CS=1000H, IP=B, DS=2000H, AX=EA66H, BX=0000H
数据和程序在计算机中都是以二进制的形式存放的
在区别程序和数据时,关键看段地址,如果段地址是ds段,说明该内存存放的是数据,如果段地址是cs段,说明该内存存放的是指令
✅ 检测点 3.2
-
mov ax,2000H mov ss,ax mov sp,0010H
-
mov ax,1000H mov ss,ax mov sp,0000H
🔍 拓展理解
- 栈的原理是汇编程序控制函数调用、保存现场的重要机制;
- 熟练掌握
DS:[address]
形式与段地址转换,有助于理解寻址方式; - 程序中变量的定义、调用、栈操作等都需精确控制寄存器值。