Pwn

汇编语言笔记(一)

Posted on 2020-01-02,6 min read

通用寄存器

8086CPU所有寄存器都是16位,放两个字节,一个字节是8位
1字=2字节=8*2
AX\BX\CX\DX这四个寄存器通常用来存放一般性的数据,被称为通用寄存器
寄存器逻辑结构如下
16位寄存器最大能存储16位16进制数,最多存放16位0或1,换成10十进制,最大值为65535
由于上一代CPU中寄存器都是8位,为了兼容,8086CPU就把AX\BX\CX\DX这四个16位寄存器可分为两个8位寄存器使用
AX分为AH,AL         *H表示高地址,*L表示低地址
BX分为BH,BL
CX分为CH,CL
DX分为DH,DL
物理地址=段地址X16+偏移地址
这里的16指的是10进制下的16,转换成16进制就是乘10
左移位数    二进制   十六进制    十进制
   0        10B       2H         2
   1        100B      4H         4
   2        1000B     8H         8
   3        10000B    10H        16
   4        100000B   20H        32
   由此发现,二进制形式左移1位,数据乘以2
   左移N位,数据乘以2的N次方
   如何完成段地址X16的运算?
   答:
   就是将二进制形式存放的段地址左移4位
   16进制数据左移一位,相当于乘以16,十进制左移1位,相当于乘以10
   X进制数据左移1位,相当于乘以X

段的划分来自于CPU,用基础地址的方式来给出内存单元的物理地址,使我们可以用分段的方式来管理内存,基础地址是起始地址,用偏移地址定位段中的内存单元。段地址必须是16的倍数,所以一个段起始地址也一定是16的倍数,偏移地址为16位,所以一个段的擦汗高难度最大位64KB
SA:段地址
EA:偏移地址

** 段寄存器**

CS和IP
CS:代码段寄存器,用来存放内存的基础地址
IP:指令指针寄存器,用来存放代码段的偏移地址
假设CS位M,IP为N
那么8086CPU及那个会从M*16+N的内存地址开始读取一条指令并执行
1.假设CS=1000H,IP为0H
那么CPU将会从1000*10+0=10000H这个地址读取第一条执行执行
第一条执行为mov ax,0123H
寄存器:数据,这种指令,占3字节
寄存器,寄存器  占2字节
汇编代码存放在内存中的内容为(B82301=mov ax,0123H)占了内存3字节
那么,这是IP(偏移值会自动+3)
2。这是CS=1000H,段地址不变,偏移地址读取上一条指令,自动+3,变成了003H
那么CPU及那个会从1000*10+3H=10003H这个地址读取第二条执行
第二条执行为mov bx,ax
占两字节,IP+2=3+2=005H
以此类推

修改CS、IP的指令

对于寄存器,我们可以用
mov ax,123H         #直接修改寄存器的值
mov bx,ax           #用其他寄存器修改值
但是mov指令不能用于设置CS、IP的值,这里介绍一个指令,jmp
jmp指令是用来跳转内存地址的
jmp 段地址:偏移地址
jmp 1000H:3
执行后,CS=1000H,IP=3H
CPU将会从10003H处,读取指令
内存地址    汇编指令
10000H      mov ax,1000H            CS=100H,IP=3
10003H      mov bx,ax               CS=100H,IP=5
10005H      jmp 100H:2              CS=100H,IP=3
当执行到10003H这个地址时,就会跳转到100*10+2=10002H地址上,本来bx的值为1000H,而jmp跳转后又执行了一次,就会一直循环

代码段
一组内存单元定义代码段,长度为<=64KB
这段内存是用来存放代码的,比如
mov ax,0000 3字节
add ax,0123H 3字节
mov bx,ax 2字节
jmp bx 2字节 bx=0123H
这段长度为10个字符的指令,存放在123B0H~123B9H的一组内存单元种,我们就把这段内存叫做代码段
段地址为123BH,长度为10个字节

寄存器(内存访问)
内存中字的存储,16位存储一个字,高8位放高位字节,低8位放低位字节
例如,我们从0地址开始存放4E20H这个数据,两个字节单元存放,4E是高地址,20是低地址,
那么存放的时候,先进后出,高地址对应高地址,低地址对应低地址
0 20H
1 4EH
2
3
DS和address
CPU要读写一个内存单元的时候,必须先给出内存单元的地址,这个和之前代码段差不多,都要给出一个段地址和偏移地址
DS寄存器,通常存放要访问数据的段地址,比如我们读取10000H单元的内容
mov bx,1000H
mov ds,bx
mov al,[0]
上面的3条指令将10000H(1000:0)中的数据读到al中
下面详细说明指令的含义
mov al,[0]
表示1000H:0偏移出内存的数据
DS寄存器不允许直接传输数据,必须通过其他的寄存器传入
mov、add、sub指令
mov 段寄存器,寄存器
#从寄存器向段寄存器传送数据

在一个程序中,有很多段
代码段 CS:代码段基础地址 IP:偏移值 存放汇编代码的内存
数据段 DS:数据段基础地址 [0]:偏移值 存放数据的内存
栈段 SS:栈段 SP:偏移值

下一篇: 汇编语言(王爽)练习题→