汇编_寄存器
文章目录
笔记19/3/5
0x00简单介绍
通常我们写汇编语言时,会接触到CPU中的主要部件,寄存器。寄存器是CPU中,我们可以用指令读写的部件,我们可以同过改变各种寄存器中的内容实现控制寄存器。这里,我学习的汇编是基于8086CPU的。不同的CPU,寄存器个数不同,结构也不同。8086有14个寄存器,分别是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW。
0x01 用到的寄存器
通用寄存器
通用寄存器:AX,BX,CX,DX;
8086寄存器都是16位的,可存放两个字节,因为这四个寄存器一般用来存放一般性的数据,所以就叫通用寄存器喏~以AX为例,其逻辑结构如下
-
这四个寄存器都可以分为两个独立的8位寄存器来用
-
AX->{AH,AL];
-
BX->{BH,BL};
-
CX->{CH,CL};
-
DX->{DH,DL}.
整个16位一起,叫做字,当分成H,L时,也就是高位,低位,那么这两个8位的数据就叫做字节 这里我们先来看一个汇编指令mov 他的格式是:mov dst,src(目的操作数,源操作数)
|
|
这里有个要注意的地方,在进行数据传送或运算时,注意指令的两个操作对象的位数应当一致。
这里先暂停讨论寄存器,我们半路来谈一下物理地址,8086有20位的地址总线,可传送20位地址,但是呢8086又是个16位的结构,其内部一次性处理数据时地址为16位,这样的话,他的寻址能力就只有 $$ 2^{16}=64KB $$ 所以8086采用一种方式在内部使用两个16位的地址,合成为一个20位的地址。 当读写内存时,CPU中的相关部件提供了两个地址,一个叫做段地址,一个叫做偏移地址,段地址和偏移地址通过总线送入一个地址加法器,然后就合成了一个20位的物理地址,然后加法器再将物理地址送入I/O控制电路,I/O控制电路再将其送往地址总线,最后传送到存储器。
|
|
这里后面涉及到一个段的概念,我们举个例子就明白了: 我们假设有一个数据存放在31A50H这个内存单元中,刚好,它是20位的地址,但是我们如何将其更好地用段来解释,我们可以这样来说
- 数据存放在3000:1A50 单元中
- 数据存放在3000段,在此段的1A50单元处
这已经很显而易见了,我们对比公式,3000是段地址,1A50是偏移地址,刚好,计算得到的物理地址是31A50,这样就比较好理解了。
DS寄存器
当CPU要读写一个内存单元时,首先要给出这个内存单元的地址,我们前面说过,内存地址,由段地址和偏移地址组成,8086CPU中有个DS寄存器,一般是来存放将要访问的数据的段地址。说白一点,就是,我们在某个段中放入了数据,那么我们就会把这个段的段地址存入DS中,方便我们进行操作,然后接着后面的指令就会对这个段内的数据进行操作,如果我们不给出DS,我们就不知道数据在哪。后面详细举例说明。。 我们先看这个段:(假设为5000段)
偏移地址 | 数据 |
---|---|
0000 | 12 |
0001 | 45 |
0002 | 26 |
如果将[0000]处的数据存入al中,那么就会存8位,因而只会将12存入,但是如果我要将同样偏移地址处的数据存入ax中,那么就会存16位,因而会将4512存入,这里是将高地址做ah,低位地址做al,所以45会在ah,12在al中。
两个例子
1.mov,add,sub命令
mov相当于赋值,add是加命令,sub是减命令,下面举例:
在5000:0000处写入20 30 40 00 12 34 11 22 44 55 00,然后进行20+30-40,3412+2211-5544,的运算,将结果分别存入,两个00的位置即[0003]与[000A]。 先介绍几个debug程序中的命令:
- r命令 查看、改变寄存器的内容
- d命令 查看内存中的内容(你会看到的形式是段地址+偏移地址)
- e命令 改写内存中的内容(我们写入数据用的就是e命令)
- u命令 查看写入的或内存中原有的机器码所对应的汇编指令。
- t命令 执行CS:IP指向的命令(一个一个执行)
- g命令 同t执行命令(整个执行)
我们首先使用DOS进入debug(这里说明一下,64位系统不支持debug,请安装dosbox+debug,或者使用虚拟机)然后使用e命令写入数据
然后使用a命令编写汇编指令
|
|
然后就可以使用T命令运行了,得到结果
2.使用masm工具
- 1建立源程序
首先是段:段有代码段,数据段,附加段,堆栈段,我们目前先使用前面两个。
段定义是 段名 segment …. 段名 ends
我们用DOS进入masm工具文件夹,使用edit编辑代码
|
|
然后保存为.asm文件,使用masm xx.asm编译 编译过程一路enter,然后得到xx.obj文件,再使用link xx.obj进行链接,然后得到xx.exe 我们直接xx.exe运行一下,再使用debug xx.exe打开 使用u命令可以反编译查看指令,我们记好指令偏移地址的起止,然后使用g=[首]:[尾]直接运行 记住ds地址,查看d [ds的地址:0000]可以看到运行结果
文章作者 halface
上次更新 2019-03-05