MASM学习x86汇编语言2 寄存器、伪指令与程序调试

MASM学习x86汇编语言2 寄存器操作与常见伪指令

  • 一、一些基本概念
  • 二、8086的寄存器
    • 1. 通用寄存器
    • 2. 段寄存器
    • 3. 标志寄存器PSW
  • 三、常用的汇编指令
  • 四、一些汇编伪指令
    • 1. 段定义 segment
      • 2. 汇编结束
      • 3. 假设 assume
      • 4. 寻址方式
  • 五、使用DosBox和Debug工具
    • 一段代码示例
      • (1) 新建一个1.asm文件:
      • (2) 启动DosBox挂载本地磁盘
      • (3) 编译
      • (4) debug加载
      • (5) 使用指令查看
  • 六、使用OllyDbg反汇编和跟踪程序

一、一些基本概念

  • 比特(bit):二进制的一位
  • 字节(byte):8比特的数据
  • 字(word):2个字节长度

二、8086的寄存器

寄存器是CPU内部高速存取数据的地方,比缓存更接近CPU的运算器。
8086是16位cpu(字长16位):

  • 其CPU一次最多可处理16位数据
  • 寄存器最大宽度位16位
  • 寄存器与PU之间的通路位16位。
  • 地址20位,最大可寻址 2 20 = 1 M B 2^{20}=1MB 220=1MB 内存空间。

这些寄存器分三种:

  • 通用寄存器:AX BX CX DX,每个寄存器又可以分为AH AL高8位和低8位分别使用。
  • 段寄存器:CS DS SS ES
  • 标志寄存器

1. 通用寄存器

8086有14个寄存器:AX BX CX DX SI DI SP BP IP CS SS DS ES PSW。

2. 段寄存器

  • CS:代码寄存器
  • IP:指令指针寄存器

CPU读取指令的寻址=CS*16+IP,即从CS:IP处执行指令。读取指令后,IP值会自动增加指向下一条指令。

  • DS:存放数据的段地址。注意8086不支持对段寄存器直接赋值,需要用另一个通用寄存器赋值给它。
  • SS:存放栈顶的段地址
  • SP:栈顶的偏移地址。
    SS:SP指向栈顶元素。 8086入栈时从高地址向低地址增长,出栈后,SS:SP指向新的栈顶。

一段内存是放代码、数据还是栈,取决非于这几个段寄存器的设置。

3. 标志寄存器PSW

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
OF DF IF TF SF ZF AF PF CF
  • OF:有符号数运算溢出标志
  • DF:在串处理指令中,控制每次操作后si、di的增减。df=0每次操作后递增,df=1每次操作后递减。
  • SF:相关指令执行后,其结果是否为负。为负则sf=1;否则sf=0。
  • ZF:相关指令执行后,其结果是否为0。为0则zf=1;否则zf=0。
  • PF:相关指令执行后,其结果的所有bit位中1的个数是否为偶数。为偶数则pf=1;否则pf=0。
  • CF:在无符号数运算时,运算结果的最高有效位是否向更高位进位或从更高位借位。是则cf=1;否则cf=0。

三、常用的汇编指令

指令 格式 作用
mov mov dest, src dest = src
add add dest, src dest = dest + src
adc adc dest, src dest = dest + src + CF
sub sub dest, src dest = dest - src
sbb sbb dest, src dest = dest - src - CF
push push src 入栈(改变SP后写内存)
pop pop src 出栈(读内存后改变SP)
pushf pushf 将标志寄存器的值压栈
popf popf 从栈中弹出数据送入标志寄存器中
and and dest, src dest = dest & src
or or dest, src dest = dest
shl shl dest, 位数 dest左移指定位数,位数大于1时必须放在cl中
shr shr dest, 位数 dest右移指定位数,位数大于1时必须放在cl中
in in al/ax, 端口号 从端口读入数据
out out 端口号, al/ax 发送数据到端口
mul mul reg/内存单元 乘法
div div reg/内存单元 除法
cmp cmp dest, src 比较
转移指令 见下 控制CPU执行指定内存的指令
串传送指令 见下 见下
int int 中断类型码 引发中断过程

四、一些汇编伪指令

汇编指令是CPU认识的对应2进制的指令,而伪指令是给编译器看的。

1. 段定义 segment

段名 segment
...
段名 ends

2. 汇编结束

end

3. 假设 assume

assume cs:codesg  ; 假设代码寄存器和下面定义的codesg相关联
codesg segment
...
codesg ends
end

4. 寻址方式

  • ()表示一个寄存器或者一个内存单元中的内容。
  • EA表示偏移地址。
  • SA表示段地址。
  • idata表示常量。

五、使用DosBox和Debug工具

64位操作系统无法直接使用Debug.exe工具了,需要安装一个DosBox,然后进行下面操作:

  1. 挂载本地磁盘,命令mount c: 本地文件夹
  2. 把debug.exe masm.exe和要调试的程序放到本地文件夹
  3. 然后就可以使用debug命令了。

常用的debug命令:

  1. R :查看更改cpu寄存器内容
  2. D:查看内存中内容
  3. E:改写内存中内容
  4. U:将内存中机器指令翻译成汇编指令
  5. T:执行一条机器指令
  6. A:以汇编格式在内存中写入一条指令

一段代码示例

(1) 新建一个1.asm文件:

code segment
assume cs:code
s:mov ax,0025h
  mov cl,2
  shl ax,cl

  mov ax,4ch
  int 21h
code ends
end s

(2) 启动DosBox挂载本地磁盘

mount c: d:/Documents/asm

MASM学习x86汇编语言2 寄存器、伪指令与程序调试_第1张图片

(3) 编译

# 提示输入内容可以一直回车
c:
masm 1.asm  
link 1.obj

这时生成1.exe

(4) debug加载

c:
debug 1.exe

(5) 使用指令查看

u

MASM学习x86汇编语言2 寄存器、伪指令与程序调试_第2张图片

六、使用OllyDbg反汇编和跟踪程序

OllyDbg通常称作OD,是反汇编工作的常用工具。
下载地址:http://www.ollydbg.de/

启动后,可以加载上篇编译的Hello.exe程序:
MASM学习x86汇编语言2 寄存器、伪指令与程序调试_第3张图片
可以看出编译器编译、链接后的代码与手写的汇编代码还是存在很大的差异。

这里可以设置断点、跟踪程序,右侧还有一些寄存器的值可以查看。

你可能感兴趣的:(#,操作系统)