實驗三 轉移指令跳轉原理及其簡單應用程式設計
阿新 • • 發佈:2021-11-27
實驗任務1
程式原始碼:
assume cs:code, ds:data data segment x db 1, 9, 3 len1 equ $ - x y dw 1, 9, 3 len2 equ $ - y data ends code segment start: mov ax, data mov ds, ax mov si, offset x mov cx, len1 mov ah, 2 s1:mov dl, [si] or dl, 30h int 21h mov dl, ' ' int 21h inc si loop s1 mov ah, 2 mov dl, 0ah int 21h mov si, offset y mov cx, len2/2 mov ah, 2 s2:mov dx, [si] or dl, 30h int 21h mov dl, ' ' int 21h add si, 2 loop s2 mov ah, 4ch int 21h code ends end start
執行截圖:
① 回答問題1:
loop指令對應的機器碼是(E2F2)16,其中(F2)16是補碼錶示的偏移量,換算成十進位制數是-14。當前loop指令的長度是2位元組,下一條指令的偏移地址是(001B)16,減去(14)10剛好是標號s1對應的偏移地址(000D)16.
② 回答問題2:
與問題1相似,機器碼中偏移量的補碼是(F0)16,對應十進位制-16。下一條指令的偏移地址是(0039)16,減(16)10得標號s2的偏移地址(0029)16.
實驗任務2
源程式程式碼:
assume cs:code, ds:data data segment dw 200h, 0h, 230h, 0h data ends stack segment db 16 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov word ptr ds:[0], offset s1 mov word ptr ds:[2], offset s2 mov ds:[4], cs mov ax, stack mov ss, ax mov sp, 16 call word ptr ds:[0] s1: pop ax call dword ptr ds:[2] s2: pop bx pop cx mov ah, 4ch int 21h code ends end start
回答問題:
從理論上分析,ax中是標號s1的偏移地址,bx中是標號s2的偏移地址,cx中是標號s2的段地址。
注意到兩條call指令一個是短轉移一個是遠轉移。執行第一個call時,將當前命令的下一條命令的偏移地址(IP)壓入棧,也就是將標號s1的偏移地址壓入棧;隨後(IP)變為記憶體單元偏移地址為0的字單元中的數值,由於程式已經將該字單元賦值為標號s1的偏移地址,所以程式看起來就是順序執行了下面的命令而沒有進行跳轉,將剛剛壓入棧的偏移地址彈出給暫存器ax;執行第二條遠轉移call時,依次將下一條指令的段地址(CS)和偏移地址(IP)壓入棧,後面的過程與之前類似。
實驗截圖:
實驗任務3
源程式程式碼:
assume cs:code, ds:data
data segment
x db 99, 72, 85, 63, 89, 97, 55
len equ $- x
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0
mov cx, len
s:
mov ah, 0
mov al, [si]
inc si
call printNumber
call printSpace
loop s
mov ah, 4ch
int 21h
printNumber:
mov bl, 10
div bl
mov bx, ax
mov ah, 2
add bl, 48
mov dl, bl ;商
int 21h
add bh, 48
mov dl, bh ;餘數
int 21h
ret
printSpace:
mov ah, 2
mov dl, 32 ;空格的ASCII碼
int 21h
ret
code ends
end start
測試截圖:
實驗任務4
源程式程式碼:
assume cs:code, ds:data
data segment
str db 'try'
len equ $ - str
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, stack
mov ss, ax
mov sp, 16
mov ax, data
mov ds, ax
mov si, 0 ;資料段偏移地址
mov cx, len ;字串長度
mov bh, 0 ;行號
mov bl, 02h ;黑底綠字
call printStr
mov si, 0
mov cx, len
mov bh, 24
mov bl, 04h ;黑底紅字
call printStr
mov ah, 4ch
int 21h
printStr:
mov ax, 0b800h
mov es, ax
push bx ;暫存顏色
mov bl, bh
mov bh, 0 ;bx中現在是行號(0-24)
mov ax, 00a0h ;一行的位元組數
mul bx
mov bx, ax ;bx得到行首偏移地址
pop ax
mov ah, al
s:
mov al, [si]
mov es:[bx+si], ax
inc bx
inc si
loop s
ret
code ends
end start
測試截圖:
實驗任務5
程式原始碼:
assume cs:code, ds:data
data segment
stu_no db '201983290485'
len = $ - stu_no
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, 0b800h
mov es, ax
mov si, 1
mov cx, 7d0h ;2000次迴圈
s:
mov byte ptr es:[si],17h ;00010111
add si, 2
loop s
mov si, 0f00h
mov cx, 80
s1:
mov byte ptr es:[si], 2dh ;-----
add si, 2
loop s1
mov si, 0f44h ;最後一行中間
mov cx, 12
mov bx, 0
s2:
mov al, [bx]
mov es:[si], al
add si, 2
inc bx
loop s2
mov ax, 4c00h
int 21h
code ends
end start
測試截圖: