組合語言第三次實驗
阿新 • • 發佈:2021-11-27
1. 實驗任務1
- task1原始碼
1 assume cs:code, ds:data 2 3 data segment 4 x db 1, 9, 3 5 len1 equ $ - x ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是3 6 7 y dw 1, 9, 3 8 len2 equ $ - y ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是9 9 data ends 10 11 code segment 12 start: 13 mov ax, data 14 mov ds, ax15 16 mov si, offset x ; 取符號x對應的偏移地址0 -> si 17 mov cx, len1 ; 從符號x開始的連續位元組資料項個數 -> cx 18 mov ah, 2 19 s1:mov dl, [si] 20 or dl, 30h 21 int 21h 22 23 mov dl, ' ' 24 int 21h ; 輸出空格 25 26 inc si 27 loop s1 28 29 mov ah, 2 30 mov dl, 0ah 31 int21h ; 換行 32 33 mov si, offset y ; 取符號y對應的偏移地址3 -> si 34 mov cx, len2/2 ; 從符號y開始的連續字資料項個數 -> cx 35 mov ah, 2 36 s2:mov dx, [si] 37 or dl, 30h 38 int 21h 39 40 mov dl, ' ' 41 int 21h ; 輸出空格 42 43 add si, 2 44 loop s2 45 46 mov ah, 4ch 47 int21h 48 code ends 49 end start
- 執行截圖
- 問題1
跳轉的位移量是-14,編譯器通過標號處的地址-loop指令後的第一個位元組的地址計算跳轉的8位位移,此例中標號s1的偏移地址為000D,loop指令後第一個位元組的偏移地址為001B,兩者相減結果為-14。
- 問題2
跳轉的位移量是-10,標號s2的偏移地址為0029,loop指令後第一個位元組的偏移地址為0039,兩者相減結果為-10。包括loop指令在內的所有迴圈指令都是短轉移,在對應機器碼中包含轉移位移而非地址。
- 反彙編截圖
2. 實驗任務2
- task2原始碼
1 assume cs:code, ds:data 2 3 data segment 4 dw 200h, 0h, 230h, 0h 5 data ends 6 7 stack segment 8 db 16 dup(0) 9 stack ends 10 11 code segment 12 start: 13 mov ax, data 14 mov ds, ax 15 16 mov word ptr ds:[0], offset s1 17 mov word ptr ds:[2], offset s2 18 mov ds:[4], cs 19 20 mov ax, stack 21 mov ss, ax 22 mov sp, 16 23 24 call word ptr ds:[0] 25 s1: pop ax 26 27 call dword ptr ds:[2] 28 s2: pop bx 29 pop cx 30 31 mov ah, 4ch 32 int 21h 33 code ends 34 end start
- 分析結果
源程式line24將下一行指令在記憶體中的偏移地址(IP)入棧,並將IP的內容修改為記憶體ds:[0]處字的內容。此前已將標號s1的偏移地址(offset s1)存至ds:[0]處,因此這條call指令執行後跳轉至標號s1處執行。s1處的指令將棧頂資料,即line25 pop指令在記憶體中的偏移地址(IP)出棧並存入暫存器ax中。
line27 call指令將下一行指令在記憶體中的段地址(CS)和偏移地址(IP)相繼入棧,並將CS和IP的內容修改為記憶體ds:[2]處雙字的內容。此前將標號s2的偏移地址(offset s2)存至ds:[2]處,將段地址(CS)存放在ds:[4]處,因此這條call指令執行後跳轉至標號s2處執行。標號s1之後的指令將棧頂資料(IP)出棧並存入暫存器bx中,在將棧頂資料(CS)出棧並存入暫存器cx中。
結論:ax中存放了標號s1處指令在記憶體中的偏移地址,bx中存放了標號s2處指令在記憶體中的偏移地址,cx中存放了標號s2處指令在記憶體中的段地址。
- 除錯驗證
反彙編後觀察標號s1、s2處指令的地址
除錯所得結果與分析相同。
3. 實驗任務3
- task3原始碼
1 assume cs:code, ds:data 2 data segment 3 x db 99, 72, 85, 63, 89, 97, 55 4 len equ $- x 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov si, offset x 12 mov cx, len 13 s:mov ah, 0 14 mov al, [si] 15 mov dl, 10 16 div dl 17 mov bx, ax 18 mov ah, 2 19 call printNumber 20 call printSpace 21 inc si 22 loop s 23 mov ah, 4ch 24 int 21h 25 26 printNumber: 27 mov dl, bl 28 or dl, 30h 29 int 21h 30 mov dl, bh 31 or dl, 30h 32 int 21h 33 ret 34 printSpace: 35 mov dl, ' ' 36 int 21h 37 ret 38 code ends 39 end start
- 執行測試
4. 實驗任務4
- task4原始碼
1 assume cs:code, ds:data 2 data segment 3 str db 'try' 4 len equ $ - str 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov si, offset str 13 mov bh, 0 14 mov bl, 2 15 call printStr 16 17 mov si, offset str 18 mov bh, 24 19 mov bl, 4 20 call printStr 21 22 mov ah, 4ch 23 int 21h 24 25 printStr:mov cx, len 26 s:mov ax, 0b800h 27 mov dx, cx 28 mov ch, 0 29 mov cl, bh 30 t:add ax, 10 31 loop t 32 mov cx, dx 33 mov es, ax 34 mov di, si 35 add di, si 36 mov al, [si] 37 mov es:[di], al 38 mov es:[di].1, bl 39 inc si 40 loop s 41 ret 42 code ends 43 end start
- 執行測試
5. 實驗任務5
- task5原始碼
1 assume cs:code, ds:data 2 data segment 3 stu_no db '201983300512' 4 len = $ - stu_no 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 call blueCurtain 12 call printStu_no 13 14 mov ah, 4ch 15 int 21h 16 printStu_no:mov ax, 0b800h 17 mov cx, 24 18 s:add ax, 10 19 loop s 20 mov es, ax 21 mov di, 0 22 mov cx, 34 23 l:mov byte ptr es:[di], '-' 24 add di, 2 25 loop l 26 mov cx, len 27 mov si, offset stu_no 28 t:mov dl, [si] 29 mov es:[di], dl 30 inc si 31 add di, 2 32 loop t 33 mov cx, 34 34 r:mov byte ptr es:[di], '-' 35 add di, 2 36 loop r 37 ret 38 39 blueCurtain:mov ax, 0b800h 40 mov es, ax 41 mov cx, 2000 42 mov si, 0 43 b:mov byte ptr es:[si].1, 23 44 add si, 2 45 loop b 46 ret 47 48 code ends 49 end start
- 執行測試