Live2d Test Env

汇编语言实验二

汇编语言实验二

1.实验任务一

使用任意一款文本编辑器,编写8086汇编源程序ex1.asm。源代码如下:

;ex1.asm
assume cs:code
code segment
mov ax, 0b810h
mov ds, ax

mov byte ptr ds:[0], 1
mov byte ptr ds:[1], 1
mov byte ptr ds:[2], 2
mov byte ptr ds:[3], 2
mov byte ptr ds:[4], 3
mov byte ptr ds:[5], 3
mov byte ptr ds:[6], 4
mov byte ptr ds:[7], 4
mov ah, 4ch
int 21h
code ends
end

要求:

  • 使用8086汇编程序编写、汇编、链接、运行、调试方法,对ex1.asm进行汇编、链接、运行,使用debug工具调试可执行文件。

使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,运行并观察结果。

  • 使用debug工具对程序进行调试
    • 使用debug加载可执行文件ex1.exe后,使用d命令查看程序段前缀PSP所占的256个字节。
    • 结合可执行文件中寄存器CX的值,使用u命令对ex1.exe进行精确反汇编。
    • 使用g命令执行到程序退出执行之前(即源码文件中line16之前),观察结果。

实验内容:

通过实验我们可以观察到,在使用masm命令之后文件夹中会多出一个ex1.obj的文件,这就是得到的目标文件,要想使其变为可执行文件,还需使用link进行连接。

汇编2

执行结果:
1.1

使用d命令查看psp的前256个字节“
汇编d命令

精确反汇编:
精确反汇编

使用g查看第16行:
汇编g命令

实验任务二

使用任意一款文本编辑器,编写8086汇编源程序ex2.asm。源代码如下:

; ex2.asm
assume cs:code
code segment
        mov ax, 0b810h
        mov ds, ax
        mov bx, 0
        mov ax, 101H
        mov cx, 4
s:      mov [bx], ax
        add bx, 2
        add ax, 101H
        loop s
        mov ah, 4ch
        int 21h
code ends
end

要求:使用8086汇编程序编写、汇编、链接、运行、调试方法,对ex2.asm进行汇编、链接、运行,使用debug工具调试可执行文件。

  • 使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行并观察结果。
  • 使用debug工具对程序进行调试。
    • 结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编
    • 灵活使用t命令、p命令、g命令,对ex2.exe进行调试。(不一定要单步,有些地方可以用g命令,一次执行多行汇编指令)

注意:单步调试时,对于循环指令loop, 中断指令int,使用t命令和p命令单步调试的区别。

  • 把ex2.asm中line9 mov cx, 4 改成 mov cx, 8 ,保存后重新汇编、链接、运行并观察结果。
  • 结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效果?在具体实现上有什么不同?

执行结果:
试验2.编译

t命令调试:
2.2

p命令调试:

2.3

2.4

g命令调试:直接跳到代码结束处:

2.5

将 mov cx, 4改为8:
2.1

通过对ex2.asm和ex1.asm对比我们可以发现,两个文件的作用都是向显存中写入数据,第一个是使用mov byte ptr 段地址:偏移地址的方法来向显存中写入数据,因为每次写进去一个byte的数据,因此4个图像总共要写8次;但是ex2.asm使用循环,每一次将ax寄存器中的数据写入缓存之中,由于ax寄存器是16位的因此只需循环4次就可以完成相同的任务;

实验任务3

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

要求:

  • 编写汇编源程序
  • 给出运行结果截图

   如程序编写正确,预期结果如图所示。(运行前先使用 命令清屏,更便于观察运行结果)

  • 把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。

程序代码如下:

;ex3.asm
assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax
    mov bx,07b8h
    mov cx,16
s:    mov dx,0237h
    mov ds:[bx],dx
    add bx,2
    loop s
    mov ax,4ch
    int 21h
code ends
end

运行结果如下:
3.1

进行两次改动:
3.2

3.3

通过比较改动的代码和运行的结果我们可以很容易的发现,mov dx 0237h,诸如此类的代码,高两位代表的是颜色,而低两位则代表的是数字的字符。

实验任务4

  • 编写完整汇编源程序,实现向内存0:2000:23F依次传送数据063(3FH)。
    • 必做
      • 综合使用[bx]和loop,编写汇编源程序灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看 0:2000:23F,确认是否将03F传送至此段内存区域。
    • 选做*
      • 利用栈的特性,综合使用loop,push实现(限定仅使用8086中已学过指令实现),编写源程序
      • 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看 0:2000:23F,确认是否将03F传送至此段内存区域。

程序代码如下:

(书上的题目要求只用9步,这里尽最大的可能去省略不必要的步骤)

;ex2.asm
assume cs:code
code segment
 mov bx,020h
 mov ds,bx
 mov bx,0
 mov cx,64
 s: mov[bx],bx
 inc bx
 loop s
 mov ax,4c00h
 int 21h
code ends
end

t命令调试:

4.1

4.2

p命令调试:
4.3

4.4

g命令跳转:
4.2g

d命令查看:

4.2d

选做内容:
使用栈来完成传输:

assume cs:code

code segment
mov ax,0000h;
mov ss,ax
mov sp,0240h
mov cx,32
mov ax,3f3eh
s: push ax
sub ax,0202h
loop s
mov ax,4c00h
int 21h
code ends

end

因为可以将栈是倒序的,因此将想要输入的区域设为栈区,栈顶应该放的就是3e3fh,然后依次类推,每push一次就将push的寄存器减去0202h;

效果:

栈入

实验任务5

教材实验4(3)(P121)
Tips: 这道练习,本质仍然是复制,只不过复制的是自身代码。填空的关键是,如何确定复制多少字节。

补全代码如下:

;ex2.asm
assume cs:code
code segment
  mov ax,cs
  mov ds,ax
  mov ax,0020h
  mov es,ax
  mov bx,0
  sub cx,5
s:mov al,[bx]
  mov es:[bx],al
  inc bx
  loop s
  mov ax,4c00h
  int 21h
code ends
end

因为要求吧mov ax,4c00h之前的代码存储,其中mov ax,4cooh int 21h总共占了5个字,因此程序的长度cx应该减去5,所以第二空使用使用sub cx,5 ;cs寄存器保存中程序的起始地址,因此需要使用ax将cs赋值给ds寄存器。

执行的最终结果:

5.4

实验结论

  • 本次实验是我熟悉了asm文件的编译链接操作的原理和过程。
  • 熟悉了debug的底层原理,能够熟练的使用t、p、g命令根据不同的情况进行不同的调试。
  • 进一步理解了loop循环的操作过程,以及应用情况,能够利用循环来解决基本的复制粘贴内存数据的简单问题。
  • 对编译器debug功能的底层有了更深一步的了解。
posted @ 2020-10-31 12:14  lszz  阅读(322)  评论(3)    收藏  举报