汇编语言实验四

Posted kwcymino

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言实验四相关的知识,希望对你有一定的参考价值。

实验内容:

  •  任务1:综合使用 loop,[bx],编写完整汇编程序,实现向内存 b800:07b8 开始的连续 16 个 字单元重复填充字数据0403H

(1)我编写的汇编程序:

assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax
    mov bx,07b8h
    mov cx,16
s:  mov [bx],0441h
    add bx,2
    loop s

    mov ax,4c00h
    int 21h
code ends
end

(2)执行的效果:

技术分享图片

(3)将源代码程序中字数据0403H→修改为0441H,再次执行的效果

技术分享图片

说明:

    通过这一实验任务,再次熟悉了向显存中写入数据,而得到不同的图案的操作。

  • 任务2:综合使用 loop,[bx],编写完整汇编源程序,实现向内存 0:200~0:23F 依次传送数据 0~63(3FH)

1. 综合使用loop, [bx], mov实现 :

(1)我编写的汇编程序:

assume cs:code
code segment
    mov ax,0020h
    mov ds,ax
    mov bx,0
    mov ax,0
    mov cx,64
 s: mov [bx],al
    add bx,1
    add al,1
    loop s

    mov ax,4c00h
    int 21h
code ends
end

(2)执行效果

技术分享图片

说明:

    在这一步,我先使用了r命令来查看各个寄存器的值,由cx可知道程序段的长度,所以直接用了g命令来一次性执行了,再用d命令可以看到传送数据成功。

2. 利用栈的特性,综合使用 loop,push 实现:

(1)我编写的汇编程序:

assume cs:code
code segment
    mov ax,0020h
    mov ss,ax
    mov sp,0040h
    mov bx,3f3eh
    mov cx,64
 s: push bx
    sub bh,2
    sub bl,2
    loop s
    
    mov ax,4c00h
    int 21h
code ends
end

(2)执行效果:

技术分享图片

说明:

  1. 在编写这个程序的时候,首先要注意到利用push来传送的是字数据,而实际上此实验任务传送的应当是字节数据,所以在赋值给bx的时候需要根据高字节数据在高地址,低字节数据在低地址的小端法特点来进行。
  2. 而入栈操作又是从高地址到低地址,所以一开始sp的赋值就应该是023f的下一位置,即0240作为栈底。相对应的bx的赋值也应该是从高到低。
  • 任务3:将“mov ax,4c00h”之前的指令复制到内存0:200处

(1)首先填写的汇编程序为:

assume cs:code
code segment
    mov ax,cs ;这里的解释详见以下说明
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,0  ;此处我先初始化cx的值为0
 s: mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end

说明:

  1. 第一处填空其实我一开始填写的是0020h,因为我认为既然要把代码段赋值到0:200处,那就是将ds的值赋为0020h,然后利用bx的值作为偏移地址,将程序段的机器码传送进这段内存单元中。但后来我发现后面进行的操作实际上是将[bx]中的数据传入到0:200处,那也就是说ds中存放的应该是程序段的段地址,也就是cs的值,所以将ds赋值为cs。
  2. 第二处填空我想先随意赋一个初值给cx,然后通过在debug下调试.exe文件时,用r命令查看cx寄存器一开始的值,就可知程序段的长度,再用u命令反汇编,即可知道“mov ax,4c00h”和“int 21h”这两条指令的长度,用cx的初始值减去这两条指令的长度即可知道需要复制的指令的长度了。
  3. 注意:cx的值为loop循环的次数,在执行本实验时,指令的复制实际上还是向内存单元写入数据,只不过写入的是程序的机器码而已,所以程序段的长度决定了要写入数据长度,即循环写入的次数,所以本实验的cx的值即为程序段的长度。

(2)按照上面我的想法进行操作,用r命令查看一开始cx的值,再用u命令反汇编:

技术分享图片

由上面可以观察到cx的初始值即程序段的长度为001Ch,后两条指令的长度总和为2+3=5,则需要复制的指令长度为001C-5=0017h

(3)然后我再修改汇编程序:

assume cs:code
code segment
    mov ax,cs
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,0017h
 s: mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s

    mov ax,4c00h
    int 21h
code ends
end

(4)执行效果:

技术分享图片

可以利用u命令反汇编观察到指令确实被写入了内存0:200处

 总结与体会:

  • 通过本次实验我更熟悉了汇编程序的编写,对程序的结构有了更深入的理解,也更熟悉了对汇编程序的编译,连接,调试,执行等操作,还复习了栈空间的使用;
  • 以上操作还有很多不足之处,例如有没有更简便的方法能够确定程序段的长度呢?我暂时只能想到这样较为繁琐的方法,但愿经过以后的学习可以解决这个问题。

 

 


以上是关于汇编语言实验四的主要内容,如果未能解决你的问题,请参考以下文章

第一章 反汇编简介

第一章 反汇编简介

实验代码审查

实验代码审查

验证码逆向专栏极验三代四代点选类验证码逆向分析

验证码逆向专栏某验四代文字点选验证码逆向分析