匯編語言實驗四


實驗內容:

  •  任務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處

 總結與體會:

  • 通過本次實驗我更熟悉了匯編程序的編寫,對程序的結構有了更深入的理解,也更熟悉了對匯編程序的編譯,連接,調試,執行等操作,還復習了棧空間的使用;
  • 以上操作還有很多不足之處,例如有沒有更簡便的方法能夠確定程序段的長度呢?我暫時只能想到這樣較為繁瑣的方法,但願經過以后的學習可以解決這個問題。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM