匯編語言課程實驗——實驗二 多個邏輯段的匯編源程序編寫與調試


實驗二 多個邏輯段的匯編源程序編寫與調試

實驗任務一

任務1-1

題干

對程序task1_1.asm進行匯編、連接,用debug加載、跟蹤調試,基於結果,回答問題。

點擊查看task1_1.asm
assume ds:data, cs:code, ss:stack
data segment
db 16 dup(0) ; 預留16個字節單元,初始值均為0
data ends
stack segment
db 16 dup(0) ;預留16個字節單元,初始值均為0
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 16 ; 設置棧頂
mov ah, 4ch
int 21h
code ends
end start

問題

  1. 在debug中將執行到line17結束、line19之前,記錄此時:寄存器(DS) = ___ , 寄存器(SS) = ___ , 寄存器(CS) = ___
  2. 假設程序加載后,code段的段地址是X,則,data段的段地址是____, stack的段地址是____。

答案

問題①
  • 寄存器(DS)= 076A;寄存器(SS)= 076B;寄存器(CS)= 076C
問題②
  • X-2;X-1

任務1-2

題干

對程序task1_2.asm進行匯編、連接,用debug加載、跟蹤調試,基於結果,回答問題。

點擊查看task1_2.asm
assume ds:data, cs:code, ss:stack
data segment
db 4 dup(0) ; 預留4個字節單元,初始值均為0
data ends
stack segment
db 8 dup(0) ; 預留8個字節單元,初始值均為0
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 8 ; 設置棧頂
mov ah, 4ch
int 21h
code ends
end start

問題

  1. 在debug中將執行到line17結束、line19之前,記錄此時:寄存器(DS) = ___ , 寄存器(SS) = ___ , 寄存器(CS) = ___
  2. 假設程序加載后,code段的段地址是X,則,data段的段地址是____, stack的段地址是____。

答案

問題①
  • 寄存器(DS)= 076A;寄存器(SS)= 076B;寄存器(CS)= 076C
問題②
  • X-2;X-1

任務1-3

題干

對程序task1_3.asm進行匯編、連接,用debug加載、跟蹤調試,基於結果,回答問題。

點擊查看task1_3.asm
assume ds:data, cs:code, ss:stack
data segment
db 20 dup(0) ; 預留20個字節單元,初始值均為0
data ends
stack segment
db 20 dup(0) ; 預留20個字節單元,初始值均為0
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 20 ; 設置初始棧頂
mov ah, 4ch
int 21h
code ends
end start

問題

  1. 在debug中將執行到line17結束、line19之前,記錄此時:寄存器(DS) = ___ , 寄存器(SS) =___ , 寄存器(CS) = ___
  2. 假設程序加載后,code段的段地址是X,則,data段的段地址是____, stack的段地址是____。

答案

問題①
  • 寄存器(DS)= 076A;寄存器(SS)= 076C;寄存器(CS)= 076E
問題②
  • X-4;X-2

任務1-4

題干

對程序task1_4.asm進行匯編、連接,用debug加載、跟蹤調試,基於結果,回答問題。

點擊查看task1_4.asm
assume ds:data, cs:code, ss:stack
code segment
start:
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
mov sp, 20
mov ah, 4ch
int 21h
code ends
data segment
db 20 dup(0)
data ends
stack segment
db 20 dup(0)
stack ends
end start

問題

  1. 在debug中將執行到line9結束、line11之前,記錄此時:寄存器(DS) = ___ , 寄存器(SS) = ___ , 寄存器(CS) = ___
  2. 假設程序加載后,code段的段地址是X,則,data段的段地址是____, stack的段地址是____。

答案

問題①
  • 寄存器(DS)= 076C;寄存器(SS)= 076E;寄存器(CS)= 076A
問題②
  • X+2;X+4

任務1-5

基於上述四個實驗任務的實踐、觀察,總結並回答:

  1. 對於如下定義的段,程序加載后,實際分配給該段的內存空間大小是 ____。
    x86asm xxx segment db N dup(0) xxx ends
  2. 果將程序task1_1.asm, task1_2.asm, task1_3.asm, task1_4.asm中,偽指令end start 改成end , 哪一個程序仍然可以正確執行?結合實踐觀察得到的結論,分析、說明原因。

分析與答案

問題①
  • [N/16向上取整]*16 Bytes
問題②
  • 經過測試,最終只有task1_4.asm可以正常運行。這是因為在前三個任務中,由於end沒有定義程序入口點,所以系統將db指令定義的數據當做指令運行,導致CS與IP寄存器出現錯誤最終導致程序運行結果不符。若使用DEBUG工具手動定義IP寄存器,則可以正確運行這些軟件。

實驗任務二

題干

編寫一個匯編源程序,實現向內存單元b800:0f00 ~ b800:0f9f連續160字節,依次重復填充十六進制數據03 04。

解答

使用debug工具的f填充命令-f b800:0f00 0f9f 03 04可以看到運行效果:
image

下面編寫相應的程序代碼:

assume cs:code

code segment
start:
    mov ax, 0b800h
    mov ds, ax
    mov bx, 0f00h;第一次寫入點定位在b800:0f00
    mov cx, 50h;80字*2=160字節
    mov ax, 0403h;按字寫入,先寫入低位然后寫入高位
s:  mov ds:[bx], ax
    add bx, 2;調整bx寫入下一個字
    loop s

    mov ah, 4ch;結束程序
    int 21h
code ends
end start

編譯連接運行程序:
image
成功運行。

注意

  • 無法直接將立即數寫入數據段寄存器ds
  • loop語句的循環次數由cx決定

實驗任務三

題干

已知8086匯編源程序task3.asm代碼片段如下。

點擊查看task3.asm
assume cs:code
data1 segment
db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends
data2 segment
db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers
data2 ends
data3 segment
db 16 dup(0)
data3 ends
code segment
start:
; ×××
mov ah, 4ch
int 21h
code ends
end start

要求

  1. 編程實現把邏輯段data1和邏輯段data2的數據依次相加,結果保存到邏輯段data3中。
  2. 在debug中加載、反匯編、調試。在數據項依次相加前,和相加后,分別查看三個邏輯段data1,data2, data3對應的內存空間,確認逐一相加后,結果的確保存在了邏輯段data3中。

解答

要求1
assume cs:code
data1 segment
   db 50, 48, 50, 50, 0, 48, 49, 0, 48, 49 ; ten numbers
data1 ends

data2 segment
   db 0, 0, 0, 0, 47, 0, 0, 47, 0, 0 ; ten numbers
data2 ends

data3 segment
   db 16 dup(0)
data3 ends

code segment
start:
    mov cx,0ah;十個數字,正好是0a
    mov si,0
    mov ax,data3
    mov ds,ax
s:  mov bx,data1
    mov es,bx
    mov al,es:[si];把data1的當前數據轉移到ax低位
    mov bx,data2
    mov es,bx
    add al,es:[si];將棧頂的data2數據與data1相加
    mov [si],al
    inc si
    loop s
    mov ah, 4ch
    int 21h
code ends
end start
要求2

已知三個數據段地址相連,且均占用16字節,故使用-d 076a:0 2f得到三行數據正好分別為data1,2,3。
image
執行程序后再次查看:
image
可見已經成功相加並保存在data3。

實驗任務四

題干

已知8086匯編源程序task4.asm代碼片段如下。

點擊查看task4.asm
assume cs:code
data1 segment
dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends
data2 segment
dw 8 dup(?)
data2 ends
code segment
start:
; ×××
mov ah, 4ch
int 21h
code ends
end start

要求

  1. 補全程序,實現把邏輯段data1中的8個字數據逆序存儲到邏輯段b中。
  2. 匯編、連接后,在debug中加載程序,運行到line15程序退出前,使用d命令查看數據段data2對應的
    內存空間,確認是否實現題目要求。

解答

要求1
assume cs:code
data1 segment
    dw 2, 0, 4, 9, 2, 0, 1, 9
data1 ends
data2 segment
    dw 8 dup(?)
data2 ends
code segment
start:
    mov cx,08h
    mov si,0
    mov ax,data1
    mov ds,ax
    mov ax,data2
    mov ss,ax;利用棧的特性實現逆序
    mov sp,010h
s:  mov ax,[si]
    push ax
    add si,2
    loop s
    mov ah,4ch
    int 21h
code ends
end start
要求2

執行后查看空間:
image
可見實現了逆序復制。

實驗任務五

題干

使用任意文本編輯器,錄入匯編源程序task5.asm。

點擊查看task5.asm
assume cs:code, ds:data
data segment
        db 'Nuist'
        db 2, 3, 4, 5, 6
data ends

code segment
start:
        mov ax, data
        mov ds, ax

        mov ax, 0b800H
        mov es, ax

        mov cx, 5
        mov si, 0
        mov di, 0f00h
s:      mov al, [si]
        and al, 0dfh
        mov es:[di], al
        mov al, [5+si]
        mov es:[di+1], al
        inc si
        add di, 2
        loop s

        mov ah, 4ch
        int 21h
code ends
end start

題目

閱讀源程序,從理論上分析源代碼的功能,尤其是line15-25,循環實現的功能是什么,逐行理解每條指令的功能。

  • 對程序進行匯編、鏈接,得到可執行文件,運行並觀察結果。
  • 使用debug工具對程序進行調試,執行到程序返回前,即line25執行之后、line27執行之前,觀察結果。
  • 源代碼中line19的作用是?
  • 修改line4里5個字節單元的值,重新匯編、鏈接、運行,觀察結果。
db 2,3,4,5,6
--> 改成:
db 5 dup(2) 或 db 5 dup(5)

基於觀察,分析、猜測這里的數值作用是什么。

解答與分析

  1. 編譯運行。
    image
    獲得了不同彩色的NUIST字母。
  2. 調試運行。
    image
    首先使用u命令找到程序結尾076b:0027,然后用-g 076b:0027命令直接執行,獲得了與直接運行相同的結果。
  3. line19代碼and al, 0dfh的作用:
    通過按位相與的方法將小寫字母轉為大寫。
  4. 修改line4后編譯運行,獲得全綠色的NUIST:
    image
    可見line4的作用為定義字母的顏色。

實驗任務六

題干

已知8086匯編源程序task6.asm代碼片段如下。

點擊查看task6.asm
assume cs:code, ds:data

data segment
    db 'Pink Floyd      '
    db 'JOAN Baez       '
    db 'NEIL Young      '
    db 'Joan Lennon     '
data ends

code segment
start:
   ; ×××
   mov ah, 4ch
   int 21h
code ends
end start

要求

  1. 補全程序,將data段中的每行第一個單詞從大寫->小寫。
  2. 在debug中加載程序,反匯編,執行到line13退出前,用d命令查看data段對應的內存空間,確認每行第一個單詞已經由大寫->小寫。

解答

要求1
assume cs:code, ds:data

data segment
    db 'Pink Floyd      '
    db 'JOAN Baez       '
    db 'NEIL Young      '
    db 'Joan Lennon     '
data ends

code segment
start:
   mov ax,data
   mov ds,ax
   mov bx,0
   mov cx,4
s: mov al,[bx]
   or al,20H
   mov [bx],al
   add bx,16
   loop s
   mov ah, 4ch
   int 21h
code ends
end start
要求2

執行后查看空間:
image
成功轉換。

實驗任務六

題干

問題場景描述:
Power idea公司1975年-1979年的基本情況如下:
image
程序task7.asm的邏輯段data中(line4-6),已經定義好了這些數據。

點擊查看task7.asm
assume cs:code, ds:data, es:table

data segment
    db '1975', '1976', '1977', '1978', '1979' 
    dw  16, 22, 382, 1356, 2390
    dw  3, 7, 9, 13, 28 
data ends

table segment
    db 5 dup( 16 dup(' ') )  ;
table ends

code segment
start:

    mov ah, 4ch
    int 21h
code ends
end start

要求

  1. 補全程序,實現題目要求,把年份、收入、雇員人數、人均收入,以結構化方式寫入table段中。
    表格中,每行數據,在邏輯段table中占16個字節,各項數據占據字節大小分配如下。其中,數據之間用空格間隔。
    image
  2. 匯編、連接后,在debug中加載、調試程序。靈活、合理使用u命令、g命令、d命令,顯示剛開始邏輯段table的數據信息,以及,結構化存入數據后,數據段table的數據信息,確認實現題目要求。

解答

要求1
assume cs:code, ds:data, es:table

data segment
    db '1975', '1976', '1977', '1978', '1979'
    dw  16, 22, 382, 1356, 2390
    dw  3, 7, 9, 13, 28
data ends

table segment
    db 5 dup( 16 dup(' ') )
table ends

code segment
start:
    mov ax,data
    mov ds,ax
    mov ax,table
    mov es,ax

    mov cx,5
    mov bx,0
    mov si,0
s1:
   mov ax,[si]
   mov es:[bx],ax
   mov ax,[si+2]
   mov es:[bx+2],ax
   add bx,16
   add si,4
   loop s1

   mov cx,5
   mov bx,5
   mov si,20
s2:
   mov ax,[si]
   mov es:[bx],ax
   mov ax,0h
   mov es:[bx+2],ax
   add bx,16
   add si,2
   loop s2

   mov cx,5
   mov bx,10
   mov si,30
s3:
   mov ax,[si]
   mov es:[bx],ax
   add bx,16
   add si,2
   loop s3

   mov cx,5
   mov si,5
s4:
   mov ax,es:[si]
   mov ax,es:[si+2]
   mov ax,es:[si+5]
   div bx
   mov es:[si+8],ax
   add si,16
   loop s4

   mov ah, 4ch
   int 21h
code ends
end start
要求2
  1. 編譯調試運行。
    查看TABLE段原始信息:
    image
  2. 使用g命令運行到結尾。
    image
  3. 再次查看TABLE段,可見已經序列化地存放了信息。
    image

實驗總結

疑難點

實驗七中若是從源變址寄存器(SI)中取值,則默認段寄存器為寄存器DS,若使用ES寄存器則必須指明。

問題

實驗五中調試運行時,若使用p命令單步調試,最后會只顯示UIST四個字母。未查明原因。


免責聲明!

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



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