首页 > 其他 > 详细

笔记2

时间:2019-03-05 19:23:48      阅读:167      评论:0      收藏:0      [点我收藏+]

笔记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(目的操作数,源操作数)

mov ax,11    #将11送入ax,相当于ax=11
mov ah,20    #将20送入ah,相当于ah=20
mov al,44    #将44送入al,相当于al=44
mov ax,bx    #将bx中的数据送入ax,相当于ax=bx
add ax,bx    #将bx与ax相加,再存入ax,相当于ax=ax+bx

这里有个要注意的地方,在进行数据传送或运算时,注意指令的两个操作对象的位数应当一致。


这里先暂停讨论寄存器,我们半路来谈一下物理地址,8086有20位的地址总线,可传送20位地址,但是呢8086又是个16位的结构,其内部一次性处理数据时地址为16位,这样的话,他的寻址能力就只有64KB
所以8086采用一种方式在内部使用两个16位的地址,合成为一个20位的地址。
当读写内存时,CPU中的相关部件提供了两个地址,一个叫做段地址,一个叫做偏移地址,段地址和偏移地址通过总线送入一个地址加法器,然后就合成了一个20位的物理地址,然后加法器再将物理地址送入I/O控制电路,I/O控制电路再将其送往地址总线,最后传送到存储器。

地址加法器采用的公式:物理地址=段地址*10H+偏移地址  #其实就是左移了四位

这里后面涉及到一个段的概念,我们举个例子就明白了:
我们假设有一个数据存放在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命令编写汇编指令

mov ax,5000
mov ds,ax
mov al,[0000]
add al,[0001]
sub al,[0002]
mov [0003],al
mov ax,[0004]
add ax,[0006]
sub ax,[0008]
mov [000A],ax

然后就可以使用T命令运行了,得到结果
技术分享图片

2.使用masm工具

  • 1建立源程序

首先是段:段有代码段,数据段,附加段,堆栈段,我们目前先使用前面两个。

段定义是
段名 segment
....
段名 ends

我们用DOS进入masm工具文件夹,使用edit编辑代码

data segment
  x1 db  27,4,?,?,?,?,?,?
  x2 dw  2345h,1234h,?,?,?,?,?,?
data ends
code segment
   assume cs:code,ds:data
   start:
       mov ax,data
       mov ds,ax
       add al,x1+1
       mov x1+2,al
       mov al,x1
       sub al,x1+1
       mov x1+3,al
       mov al,x1
       mul x1+1
       mov x1+4,al
       mov al,x1
       cbw
       div x1+1
       mov x1+6,al
       mov x1+7,ah
       mov ax,x2
       add ax,x2+2
       mov x2+4,ax
       mov ax,x2
       sub ax,x2+2
       mov x2+6,ax
       mov ax,x2
       mul x2+2
       mov x2+8,ax
       mov x2+10,dx
       mov ax,x2
       cwd
       div x2+2
       mov x2+12,ax
       mov x2+14,dx
       mov ah,4ch
       int 21h
code ends
end start

然后保存为.asm文件,使用masm xx.asm编译
编译过程一路enter,然后得到xx.obj文件,再使用link xx.obj进行链接,然后得到xx.exe
我们直接xx.exe运行一下,再使用debug xx.exe打开
使用u命令可以反编译查看指令,我们记好指令偏移地址的起止,然后使用g=[首]:[尾]直接运行
记住ds地址,查看d [ds的地址:0000]可以看到运行结果
技术分享图片

笔记2

原文:https://www.cnblogs.com/c4ri5j/p/10478702.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!