汇编语言编译环境,汇编寄存器,栈使用 笔记

前言

理论学习资料:王爽 《汇编语言》,本文内容覆盖1-3章的内容,使用工具 emu8086。emu8086能够模拟8086CPU的汇编编译,而且不需要额外的复杂配置。

SASM和visual studio汇编的运行环境依赖于实体机,实体机目前均是32位以上的机器,对初学者不够友好。emu8086能够完整的模拟8086汇编,而且汇编的编写和调试均在视图环境下操作,很友好。

以汇编代码的例子为入口,在以后的时间能够更快的回顾汇编知识。

简单理解通用寄存器

8086CPU有AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW。

汇编寄存器有很多个,不用一次性记住和一次性了解,用到什么寄存器,再记住哪个寄存器,用不到的就暂且不用管它。

CPU在计算运行过程中,会产生很多临时数据参与计算运行。在高级语言中,比如代码 int a = 1;,在汇编语言中int a=1;代码这个数据就会1放到寄存器ax的通用寄存器中去了 mov ax, 1

8086CPU有AX, BX, CX, DX寄存器为通用寄存器,通用寄存器存放的是一般性数据;其他的寄存器是配合着通用寄存器进行相关的操作。对于寄存器的用法,只要记住两类即可;一类是通用寄存器,另一类是配合通用寄存器操作的寄存器。

配合通用寄存器操作的寄存器都怎么配合,以后碰到一个再学一个就行,没有必要一次性全部记住。就像学习高级语言一样,没有一个人敢说对某个高级语言精通,面面俱到。

理解汇编语言中的代码段

在计算机系统中一般会学到内存分页,将多少个内存单元(8086每个字节为一个内存单元)分成一页,然后进行内存管理;分页只是方便操作系统的内存管理,在进入CPU时,对CPU来说是透明的(cpu无需知道你是怎么进行内存管理的,只要给它想要的数据就行)。

这里搞清楚一点,汇编其实跟操作系统没多大关系,汇编执行时凌驾于操作系统上的,汇编直接对硬件进行操作,对寄存器进行读写从而达到控制硬件目的。在CPU中,程序员能够用指令读写的部件只有寄存器。

在CPU运行时,读取数据是按照来的,CPU要读取代码数据时,代码数据是按照来划分代码数据,内存数据也是按照来划分的。

如下图,CPU需要代码段数据时,CS寄存器中存放代码段的首地址。根据CS寄存器就知道一块代码存放在哪里了。具体想要这块代码中哪个内存单元的代码呢,就需要再来一个寄存器来指向代码段中哪个内存单元的代码;这个寄存器就是IP寄存器,IP(POINT的简写,指向的意思)。
在这里插入图片描述

可以知道CS与IP配合就能得出那块代码了,在专业术语中:代码段基地址与偏移;代码段基地址存放在CS中,偏移存放在IP中。

在emu8086断点跟踪调试jmp bx。cs存放的段地址不变,ip变为bx中的内容。

mov ax, 0000H
add ax, 0123H
mov bx, ax
jmp bx  ;jmp bx,cs存放的段地址不变,ip变为bx中的内容

CS在开始阶段的内容为0700H,jmp bx后,IP改变了。如果想要CS寄存器内容改变,需要执行指令jmp cs:ip如同jmp 2AE3:3 这种指令 CS = 2AE3, IP = 0003H。
在这里插入图片描述

理解汇编语言中的数据段

CPU想要读取一个内存单元时,跟读取代码段类似,需要制定段的基地址(首地址)和数据段的偏移;即可读取内存中相应内存单元的数据了。

比如读取10001H(1000H:1)数据

mov bx, 1000H
mov ds, bx
mov al, [1]

[...] 表示一个内存单元,[1]表示cs指向的段中的偏移地址。之所以使用低八位al寄存器接受,是因为一个内存单元一个字节,一个字节为8位。

还能倒过来,向内存中写入数据,向1000H:0里面写入02H内容

mov ax, 1000H
mov ds, ax
mov bl, [1]
mov [0], 02H

如下图,BX低八位变成01H,内存1000H:0变为对应的内容了。

一个字节是由两位十六进制数组成。

最常用的字节是八位的字节,即它包含八位的二进制数。十六进制一般用数字0到9和字母A到F(或a - f)表示,其中:A ~ F表示10 ~ 15,这些称作十六进制数字。十六进制数转换成二进制数:把每一个十六进制数转换成4位的二进制数,就得到一个二进制数。

十六进制数字与二进制数字的对应关系如下:0000 -> 0、0001 -> 1、0010 -> 2、0011 -> 3、0100 -> 4、0101 -> 5、0110 -> 6、0111 -> 7、1000 -> 8、1001 -> 9、1010 -> A、1011 -> B、1100 -> C、1101 -> D、1110 -> E、1111 -> F。

因此,1个16进制数对应4个二进制数位,2个16进制数位对应8个二进制数位,及1个字节。
在这里插入图片描述
在上图中,Random Access Memory(RAM)内存查看的框框中,我们能够查看RAM存储内容,那么如何查看这里的内容呢。

首先要了解我们的CPU是多少位的,本文是针对8086CPU为16位,中间的短横线为分割符前面为0-7位,后面8 - F位置(0 - F正好为16位)目的是方便查看。图中每个位置为一个内存单元(一个字节) ,及时在32位和64位的系统中,十六进制表示的方式依然如此:两个十六进制表示一个字节(因为一个字节是位二进制表示,一个十六进制的由位二进制表示)

理解汇编语言中的栈段

栈中两个重要的指令,push和pop
push 寄存器 ;将一个寄存器中的数据入栈
pop 寄存器 ;出栈,用一个寄存器接收出栈的数据

栈段的数据由SS:SP来定位,段基地址SS寄存器,栈顶SP寄存器。SP寄存器始终指向栈顶位置。

在8086CPU中,压栈数据SP = SP - 2,出栈SP = SP + 2。在入栈是减,出栈是加这种反常的操作,在上一篇的汇编语言笔记中有记录解释 汇编语言笔记,欢迎查看。

水平有限,存在错误,请指出。谢谢!

猜你喜欢

转载自blog.csdn.net/Hello_Ray/article/details/113198244
今日推荐