实验2 汇编源程序编写与汇编、调试


一、实验结论

实验一

  1.首先创建ex1.asm文件如下:

   

   2.使用masm工具对ex1.asm进行汇编:

  

   并没有发现错误。

  

   此时可以发现,同文件夹下多出了一个EX1.OBJ文件

  *.OBJ文件表示目标文件。

  3.对.OBJ文件进行连接操作,以得到执行文件

  

   此时得到了一跳错误消息:

LINK  :  warning L4021 :  no stack segment

  查阅资料发现这个错误代表程序中没有安排堆栈段。该警告可忽略。

  此时发现,同文件下得到了Ex1.exe文件

   4.运行EX1.EXE

   发现得到了预期结果

  5.使用debug工具对其进行调试

  首先查看程序段前缀PSP的256个字节中的内容:

  使用-d命令

      

   查看寄存器中的值

  

 

 

   可以发现 CX= 0031H,则指令长度为31,CS:IP为076A:0000,表示第一条指令地址

  可以得到反汇编指令为 

-u 076A:0000 30

  可以反汇编得到指令如下:

  

   经过查阅资料发现,int 21 是调用了21号系统中断,

        

  使用g命令执行到line16退出执行之前:

  g命令后面可以跟地址和断点,即格式为 g [=address] [breakpoints],运行到内存指定位置的代码后暂停,如果不加参数默认是从当前IP运行到程序结束。

  可以得到命令为:

-g 0028

  

实验二

ex2.asm代码如下:

         

   masm进行汇编:

         

   link工具进行连接:

        

  任然是这个warning,可以忽略

  运行ex2.exe:

  

   使用-r命令查看寄存器中的值。

     

 可以发现(CX)=1c,指令长度为1c,(CS:IP)=076A:0000H

得到反汇编命令:

-u 076A:0000 1b

反汇编结果:

首先使用t,执行了 mov ax,b810

 

 使用t命令,执行 mov ds,ax

 使用p命令,类似T命令,不过遇到子程序调用的时候直接执行完子程序代码,不会进入子程序逐条执行,可以理解为step over。另外,在遇到循环指令时,会直接执行到CX=0。

-p

 此时执行到了mov ax,101

快进到loop s

 此时使用p命令,可以发现出现图案

 在使用g命令

将4改为8

结论:

ex1与ex2的效果相同,都是改变屏幕上固定位置显示的内容,在形式上

ex2采用了loop循环与[bx]的方式

ex1采用了直接改变的形式。

ex2代码简洁,ex1代码直接。

实验三

1.代码:

assume cs:code
code segment
mov ax, 0b800h
mov ds, ax
mov bx, 07b8h
mov ax, 0237h
mov cx, 16h
x:  mov [bx], ax
add bx, 2h
loop x
mov ah, 4ch
int 21h
code ends
end
经过汇编和连接得到ex3.exe文件,
 

2.经过汇编和连接得到ex3.exe文件,步骤与上雷同,不再赘述。

可以得到运行结果:

 

 

3.将填充的字数据,从0237H改为0239H,汇编连接运行后得到结果如图所示:

 

 

 4.将填充的字数据,从0237H改为0437H,汇编连接运行后得到结果如图所示:

 

 

 

可以联想:高位字节存放的是显示内容的颜色,低位字节存放的是显示的内容。

实验四

任务:编写完整汇编源程序,实现向内存0:200~0:23F依次传送数据0~63(3FH)。
1)综合使用 [bx] 和 loop,编写汇编源程序实现,源程序如下:
assume cs:code
code segment
mov ax, 0
mov ds, ax
mov bx, 200h
mov ax, 0
mov cx, 40h
s:  mov [bx] ,al
inc ax
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end

经过汇编连接过后得到exe文件,运行如下:

 

 

 可以发现此时0:200 到0:23F 中的内容都为0。

使用g命令运行程序,可以发现0:200-0:23F内存中的内容被替换为了0-3F

实验五

填空以后的代码:

assume cs:code
code segment
mov ax, cs(填空)
mov ds, ax
mov ax, 0020h
mov es, ax
mov bx, 0
mov cx, 1CH(填空)
s:  mov al,[bx]
mov es:[bx], al
inc bx
loop s
mov ax, 4c00h
int 21h
code ends
end
很明显该复制的数据应该来自代码本身所对应的机器码。
所以此时 ds寄存器的值应该等于 cs寄存器的值,这样才可以从指定区域复制代码。
cx中的值代表的是循环次数,
随意填入一个数据,汇编连接运行后得到下列截图:

 

 故猜测cs=1cH,运行得到结果:

 

 可以发现指令已经被复制到了相应位置。

二、实验总结

cx寄存器中一般用来存放整个程序的长度  单位是字节。

在loop指令的循环中  通过指定cx寄存器的值来确定循环的次数  每次循环结束后cx的值会自动减1。

文本编辑器编写程序时程序中的十六进制数需要带上h,否则再执行过程中会被当成十进制数。但是在debug内部写入时不用,因为debug默认数据是16进制的。

在进行复制时,要注意循环次数和开始位置。

posted @ 2020-11-05 23:49  艾瑞克Aric  阅读(362)  评论(2)    收藏  举报