8086汇编-汇编环境搭建
本帖最后由 啥都不会 于 2022-4-18 20:39 编辑> 本帖最后由 啥都不会 于 2022-4-18 14:50 编辑
> 本帖最后由 啥都不会 于 2022-4-18 14:44 编辑
> 本帖最后由 啥都不会 于 2022-4-18 14:33 编辑
> 本帖最后由 啥都不会 于 2022-4-18 14:27 编辑
> 本帖最后由 啥都不会 于 2022-4-17 23:57 编辑
> 本帖最后由 啥都不会 于 2022-4-17 23:37 编辑
# 运行环境:
WIN10
# 涉及工具:
DosBox
# 编程语言:
汇编语言
# 以下为主题内容:
这篇笔记部分参考了 "王爽《汇编语言》"
# 汇编学习环境搭建
1. ([https://pan.baidu.com/s/1XgMfM9VeUYV7Xb_n3JfbbQ?pwd=9emc](https://pan.baidu.com/s/1XgMfM9VeUYV7Xb_n3JfbbQ?pwd=9emc))
2. 安装配置DOSBox虚拟机

3. 将 masm 目录放到自定义的目录中

4. 进入 DOSBox 安装目录,双击 DOSBox 0.74 Options.bat 文件,此时会自动打开配置文件 dosbox-0.74.conf 文件

5. 在配置文件末尾添加如下命令:
```masm
mount C "masm目录"
c:
```
如下图所示:

# 汇编语言程序设计编程调试过程
1. 编写 .asm 源程序
2. 使用 masm 汇编源程序
3. 使用 link 连接目标程序
4. 调试 exe 可执行程序

- 编辑器:编写汇编代码的工具,记事本、nodepad++、vscode等等
- 汇编-编译器:将汇编代码按照汇编语法解析成机器指令。汇编成功后生成 obj 文件。
- 链接器:将一个或多个 obj 文件链接在一起,生成二进制可执行文件。
- 调试器:调试生成的二进制文件
范例:



# Debug调试程序
debug 命令

## 调试 hello.exe
1. 调试程序:debug 程序名

2. 指令 R 显示当前寄存器的值

> 在寄存器值的下一行,显示程序将要执行得指令
3. 单步调试
指令 t,对程序进行单步调试(执行一条汇编指令)

> 执行完第一条指令后,AX寄存器得值改变了
4. 查看程序汇编指令
指令 u,查看程序运行时得汇编指令

5. 修改汇编指令
指令 a,修改汇编指令(默认是从 cs:0 的位置处修改指令)

输入 "a 物理地址",修改指定位置的指令

> 在逻辑地址处,再次输入 enter 结束a功能
6. 退出调试器
输入 q 退出 debug 调试器

> 其他指令不常用,后面调试大一点的程序会用到 p 和 g 指令,后面等用到再说,其它指令不常用,就不再演示了。
# 寄存器
CPU 是由运算器、控制器、寄存器等器件构成,这些器件都是靠内部总线相连。之前所说的总线,相对于 CPU 来说是外部总线。内部总线实现 CPU 内部各个器件之间的联系,外部总线实现 CPU 和主板上其他器件(内存条、硬盘、显卡等等)的联系。
CPU 内部器件功能描述:
- 运算器进行的信息处理;
- 寄存器进行的信息存储;
- 控制器控制各器件进行工作;
- 内部总线连接各种器件,在它们之间进行数据传送。
CPU 就是使用运算器处理寄存器中的数据,再将结果传给寄存器。
不同的 CPU 寄存器的个数、结构是不相同的。8086 CPU 有 14 个寄存器,每个寄存器有一个名称。这些寄存器是:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、flag。


"数据寄存器" 和 "变址寄存器" 后面的功能描述,指的是在特定环境下通用寄存器的用途。一般情况下你可以用其中任一寄存器传输数据。数据寄存器 BX 也可用作变址寄存器,因为 8086 存储指针的寄存器不够用,所以拓展了 bx 寄存器的功能(现在不理解没关系,后面写代码写多了就懂了)。
指针寄存器:SP(永远指向栈顶指针)和 BP(永远指向栈底指针)是堆栈中使用的寄存器,一般涉及到堆栈时才会使用。
> 变址寄存器和指针寄存器都是用来存储内存地址的。它们之间的唯一区别就是,指针寄存器用在堆栈数据传送和存储中,而变址寄存器用在一般数据传送和存储中。
IP指令指针:表示将要执行哪个地址的指令。每次执行完当前指令,IP 会自动加 1 指向下一条指令,这也就是计算机能实现自动化的原因。
段寄存器:段寄存器用来存储相应段的段值。比如
DS 存储数据段段值,CS 存储代码段段值,SS 存储堆栈段的断值,ES 存储扩展段段值(因为在8086中段寄存器不够用,所以加了 ES
作为备用段寄存器)。段寄存器主要是为了解决 8086 计算机寻址空间不足的问题,这个后续会进行解释。
flags(标志寄存器或程序状态字PSW寄存器)寄存器:包含状态标志位和控制标志位。状态标志位用来表示逻辑运算结果,而控制标志位就是用来控制计算机运行的。
## 数据寄存器
8086 CPU 的所有寄存器都是 16 位的,可以存放两个字节。AX、BX、CX、DX 这 4 个寄存器通常用来存放一般性的数据,被称为数据寄存器。
以 AX 为例,寄存器的逻辑结构图如下:

一个 16 位寄存器可以存储一个 16 位的数据,数据在寄存器中的存放情况如下:

8086 CPU 上一代中的寄存器都是 8 位的,为了保证兼容,让原来基于上一代 CPU 编写的程序可以稍加修改就能在 8086 上。因此 8086 CPU 的 AX、BX、CX、DX 这 4 个寄存器都可以分为两个独立的 8 位寄存器来用:
- AX 可分为两个独立的寄存器 AH 和 AL
- BX 可分为两个独立的寄存器 BH 和 BL
- CX 可分为两个独立的寄存器 CH 和 CL
- DX 可分为两个独立的寄存器 DH 和 DL。
以 AX 为例,8086 CPU 的 16 位寄存器分为两个 8 位寄存器的情况如下:

AX 的低 8 位(0位~7位)构成了 AL 寄存器,高 8 位(8位~15位)构成了 AH 寄存器。AH 和 AL 寄存器是可以独立使用的 8 位寄存器。下图展示了 16 位寄存器及 它所分成的两个 8 位寄存器的数据存储情况。


**示例:**
通过汇编指令控制 CPU 进行工作,如下入的几条指令


下图 CPU 执行表中所列的程序段中的每条指令后,对寄存器中的数据进行的改变。




上图中的最后一条指令 add ax,bx的 AX 数据为:8226H+8226H=1044CH,但是 AX 是16 位寄存器只能存储 4 位 16 进制数据,所以最高位 1 不能在 ax 中保存,ax 中的数据为:044CH
一个 16 位寄存器被分为两个 8 位寄存器使用的时候,独立出来的 8 位寄存器与原来的 16 位寄存器无关。如果使用 AH 或 AL 时,当数据超过 8 位时多出来的数据会被丢弃。
下图所列的是一段程序的执行情况:



上图中的最后一条指令 add al,93H ,在执行前,al中的数据为 C5H,相加后所得的值为:C5+93=158H,但是 al 为 8 位寄存器,只能存储两位 16 进制的数据,所以最高位的 1 丢失,ax 中的数据为:0058H
## 变址和基址寄存器
变址和指针寄存器主要用于存放某个存储单元地址的偏移,或某组存储器单元开始地址的偏移,作为存储器(短)指针使用。
作为寄存器,可以保存16位算数逻辑运算中的操作数和运算结果,有时运算结果就是需要的存储单元地址的偏移。**区别:**不可以分解成8位寄存器使用。
主要作用是实现多种存储器操作数的寻址,从而方便的实现对多种类型数据的操作。
SI和DI寄存器称为变址寄存器。在字符串操作中,规定由SI给出源指针,由DI给出目的指针,所以SI也称为源变址寄存器,DI也称为目的变址寄存器。SI和DI也可以作为一般存储器使用。
举例:
```masm
mov si,0
mov ax,
mov di,0
mov ax,
mov si,offset mess
mov di,offset mess
```
BP和SP寄存器称为指针寄存器。BP主要用于给出堆栈中数据区基址的偏移,从而方便地实现直接存取堆栈中地数据,所以BP也称为基指针寄存器。正常情况下,SP也只作为堆栈指针使用,即保存堆栈栈顶地址的偏移。堆栈就是一块内存用来存储数据的,只不过存储数据的方法不一样,具体内容后面会详细解释。
举例:
```masm
mov ax,stack
mov ss,ax
mov sp,16
push bp
mov bp,sp
```
谢谢分享 图片格式问题 谢谢分享 感谢楼主 谢谢分享 感谢楼主 谢谢分享 谢谢分享 感谢楼主