8

实验1 用机器指令和汇编指令编程

 3 years ago
source link: http://www.cnblogs.com/Lvatsit/p/13835789.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

实验1.1 查看CPU和内存,用机器指令和汇编指令编程

实验任务

(1)使用Debug,把以下程序段写入内存,逐条执行,观察每条指令执行后CPU中相关寄存器中的内容变化。

  • b8 20 4emov ax,4e20
  • 05 16 14add ax,1416
  • bb 00 20mov bx,2000
  • 01 d8 add ax,bx

写入指令前的内存单元:

JrmMzay.png!mobile

用e命令以机器码形式写入前两条指令:

FbqeauF.png!mobile

用a命令以汇编指令形式写入后两条指令:

EVZni2y.png!mobile

使用d命令查看内存中被写入的指令:

iAzMfaj.png!mobile

使用u命令反汇编内存中被写入的指令:

7NJv2m2.png!mobile

使用t命令逐步执行指令,观察内存单元的变化:

rmeAji.gif!mobile

所有指令执行完毕后,寄存器AX=8236,BX=2000,CS=0000,IP=020B。

(2)将以下3条指令写入从2000:0开始的内存单元,利用这三条指令计算2的8次方。

  • mov ax,1
  • add ax,ax
  • jmp 2000:0003

首先通过r指令修改CS、IP的值为2000和0:

JVb2ueN.png!mobile

将3条指令写入内存单元:

i6ZNRbM.png!mobile

BJFRvy.png!mobile

从2000:0003开始,使用t命令执行至2000:0007连续执行

jAfUryn.gif!mobile

Z7Bruiv.png!mobile 注意此处AX=0100为16进制表示,用10进制表示即为256即2的8次方。

(3)查看内存中的内容

PC机主板上的ROM中写有一个生产日期,在内存FFF00H~FFFFFH的某几个单元中,尝试找到这个生产日期并试图改变它。

NBRryy.png!mobile

在FFF0:00F0处找到生产日期1992.01.01。注:此处为DOSBox虚拟环境下的生产日期。

试图修改该日期,发现无效。

B3emAz.png!mobile

分析:地址C0000~FFFFF的内存单元为只读存储器地址,向其中写入内容是无效的。

(4)向内存从B8100H开始的单元中填写数据,观察产生的现象。如:

-e B810:0000 01 01 02 02 03 03 04 04

ba2iEjr.png!mobile

JBFBvyQ.png!mobile

分析:地址A0000~BFFFF的内存单元是现存的范围,向其中写入数据,这些数据就会被显卡输出到显示屏上。

在这个过程中,内存地址决定了像素点的位置,一个字节中的高4位决定符号的形状,而后四位决定符号的颜色。

——————————————————————————————————————————————————————————————————

实验1.2 寄存器的内存访问

实验任务

(1)使用e命令修改内存单元 0020:0~0020:f 中的数据,并查看该修改操作是否正确写入数据。

IJZFraN.png!mobile

如图,写入数据正确。

(2)将P74页的程序写入内存,逐条调试,根据指令执行后的实际运行结果填空。

使用a指令写入程序:

amArmei.png!mobile

单步调试:

yyuu6vf.gif!mobile

Ubi2iqQ.gif!mobile

uauiMvi.gif!mobile

过程分析:前两条指令,意在将ds即数据区寄存器的地址设为ffff,在这之后对于内存地址的调用[X],即可看作读取地址ds:x单元处的数据。

第3、4条指令,意在将栈底设置为2200,在执行第四条指令时,紧接执行了其下的第五条指令mov sp,0100设置栈顶位置。

第7~10条指令,借助ds数据区寄存器对于内存中的内容进行查改设定。

第11~14条指令,通过对于ax、bx的出栈入栈操作,实质上执行了交换ax、bx寄存器的内容。这里的push和pop指令利用到了栈地址和

栈顶指针,即先前设置的ss:sp。

第15~16条指令,对于栈的一些使用。

(3)将图3.19的7行指令写入内存,进行一些修改操作,并分析原因。

将指令写入内存:

36ZZRfF.png!mobile

使用e命令修改2000:0~2000:f的值为0:

i63qyy.png!mobile

逐步调试:

mqaIZvN.png!mobile

y2e2aq.gif!mobile

fArYJr3.gif!mobile

内存分析:首先我们将2000:0~2000:f设置为了0,但经过mov sp,ax 和mov sp,10指令后,此时初始的栈底为2000,栈顶为2000:10我们发现,

虽然我们还没有向栈内push内容,但2000:0~2000:f这段内存中被写入了一些内容,包括CS和IP寄存器的值被放在栈后,以及在此

状态下的AX值。经过两次压栈操作,我们可以通过查看内存看见,ax的值被正确的压入栈中,如果在程序执行完毕后继续执行空程

序,栈后保存的CS、IP值也随之变化,

成因猜测:可能栈在创建过程中会保留记录当时的CS、IP值和一些寄存器的状态,同时在对栈进行操作的过程中,机器会动态维护这些状态。

实验总结:

通过本次实验,我从以下几个方面认识了汇编语言:

  1. 常用的debug指令的使用
    1. -a cs:ip在cs:ip中写入指令
    2. -r  [寄存器]  观察寄存器状态[修改寄存器的值]
    3.        -d [内存地址] [l长度] 观察内存地址中指定长度的内容
    4.        -u [内存地址] [l长度] 将内存地址中指定长度的二进制数据反汇编成汇编语言。
    5.        -e [内存地址] 修改指定内存地址的内容
    6.        -t[=内存地址] 从指定内存地址开始单步执行汇编指令
  2. 各种寄存器的作用
    1. AX、BX、CX、DX通用寄存器,长16位,其中可以分为AH、AL两个8位寄存器使用
    2.        SS、SP栈底寄存器和栈顶寄存器,通过设置SS、SP的值可以创建栈,当使用push/pop命令时从栈顶进行操作。
    3.        DS数据段寄存器,当使用[X]读取内存时,会读取DS:X内存的内容
    4. CS、IP寄存器,指令寄存器,当执行指令或者编写指令时,将指令写在CS段。
  3. 内存的存放方法
    1. 字在内存中存储时,要用两个地址连续的内存单元来存放。字的低位字节放在低地址单元,高位放在高地址单元。
    2. DOS系统中地址0~9FFFF为主随机存储器,A0000~BFFFF为显存单元,C0000~FFFFF为只读存储器。
    1. 栈在创建过程中会保留记录当时的CS、IP值和一些寄存器的状态,同时在对栈进行操作的过程中,机器会动态维护这些状态。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK