實驗3 轉移指令跳轉原理及其簡單應用編程
實驗任務1
1 assume cs:code, ds:data 2 data segment 3 x db 1, 9, 3 4 len1 equ $ - x ; 符號常量, $指下一個數據項的偏移地址,這個示例中,是3 5 y dw 1, 9, 3 6 len2 equ $ - y ; 符號常量, $指下一個數據項的偏移地址,這個示例中,是9 7 data ends 8 code segment 9 start: 10 mov ax, data 11 mov ds, ax 12 mov si, offset x ; 取符號x對應的偏移地址0 -> si 13 mov cx, len1 ; 從符號x開始的連續字節數據項個數 -> cx 14 mov ah, 2 15 s1:mov dl, [si] 16 or dl, 30h 17 int 21h 18 mov dl, ' ' 19 int 21h ; 輸出空格 20 inc si 21 loop s1 22 mov ah, 2 23 mov dl, 0ah 24 int 21h ; 換行 25 mov si, offset y ; 取符號y對應的偏移地址3 -> si 26 mov cx, len2/2 ; 從符號y開始的連續字數據項個數 -> cx 27 mov ah, 2 28 s2:mov dx, [si] 29 or dl, 30h 30 int 21h 31 mov dl, ' ' 32 int 21h ; 輸出空格 33 add si, 2 34 loop s2 35 mov ah, 4ch 36 int 21h 37 code ends 38 end start

tip:理解運算符offset、偽指令equ、預定義符號$的靈活使用。 通過line5、line8,以及數據項的數據屬性(字節、字、雙字,等),可以方便計算出連續數據項的個數,而無需人工計數。
注*: 符號常量len1, len2不占用數據段內存空間
問題①
① line27, 匯編指令 loop s1 跳轉時,是根據位移量跳轉的。通過debug反匯編,查看其機器碼,分析其跳轉的位移量是多少?(位移量數值以十進制數值回答)從CPU的角度,說明是如何計算得到跳轉后標號s1其后指令的偏移地址的。

跳轉的位移量是14,CPU通過loop指令下一條指令的地址減去s1所在地址得到偏移地址。
問題②
② line44,匯編指令 loop s2 跳轉時,是根據位移量跳轉的。通過debug反匯編,查看其機器碼,分析其跳轉的位移量是多少?(位移量數值以十進制數值回答)從CPU的角度,說明 是如何計算得到跳轉后標號s2其后指令的偏移地址的。

位移量是16,CPU通過loop指令下一條指令的地址減去s1所在地址得到偏移地址。
問題③
③ 附上上述分析時,在debug中進行調試觀察的反匯編截圖
見上述截圖。
實驗任務2
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
問題①
① 根據call指令的跳轉原理,先從理論上分析,程序執行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ?
call在跳轉之前,會把當前ip或者cs和ip先做入棧操作,然后再跳轉。
所以,ax里是pop ax的地址,bx里是px bx的地址,cx里是cs的值。
問題②
② 對源程序進行匯編、鏈接,得到可執行程序task2.exe。使用debug調試,觀察、驗證調試 結果與理論分析結果是否一致。


實驗任務3
針對8086CPU,已知邏輯段定義如下:
1 data segment 2 x db 99, 72, 85, 63, 89, 97, 55 3 len equ $- x 4 data ends
編寫8086匯編源程序task3.asm,在屏幕上以十進制形式輸出data段中這一組連續的數據,數據和數據 之間以空格間隔。
要求:
編寫子程序printNumber
功能:以十進制形式輸出一個兩位數
入口參數:寄存器ax(待輸出的數據 --> ax)
出口參數:無
編寫子程序printSpace
功能:打印一個空格
入口參數:無
出口參數:無
在主體代碼中,綜合應用尋址方式和循環,調用printNumber和printSpace, 實現題目要求。
tip:int 21h中的2號子功能說明如下
; 功能:輸出單個字符
mov ah, 2
mov dl, ×× ; ××是待輸出的字符,或其ASCⅡ碼值
int 21h
代碼如下:
1 assume cs:code, ds:data 2 3 data segment 4 x db 99, 72, 85, 63, 89, 97, 55 5 len equ $- x 6 data ends 7 8 code segment 9 start: 10 mov ax,data 11 mov ds,ax13
12 mov bx,0
13 mov cx,len 14 mov byte ptr ds:[len],10 15 16 s: mov ax,0 17 mov al,ds:[bx] 18 call printNumber 19 call printSpace 20 inc bx 21 loop s 22 23 mov ah,4ch 24 int 21h 25 26 printNumber: 27 div byte ptr ds:[len] 28 mov dx,ax 29 or dl,30h 30 mov ah,2 31 int 21h 32 33 mov dl,dh 34 or dl,30h 35 mov ah,2 36 int 21h 37 38 ret 39 40 printSpace: 41 mov dl,' ' 42 mov ah,2 43 int 21h 44 ret 45 46 code ends 47 end start

實驗任務4
針對8086CPU,已知邏輯段定義如下:
1 data segment 2 str db 'try' 3 len equ $ - str 4 data ends
編寫8086匯編源程序task4.asm,在屏幕上以指定顏色、指定行,在屏幕上輸出字符串。
要求:
編寫子程序printStr
功能:在指定行、以指定顏色,在屏幕上顯示字符串
入口參數 字符串首字符地址 --> ds:si(其中,字符串所在段的段地址—> ds, 字符串起始地址的偏 移地址—> si) 字符串長度 --> cx 字符串顏色 --> bl 指定行 --> bh (取值:0 ~24)
出口參數:無
在主體代碼中,兩次調用printStr,使得在屏幕最上方以黑底綠字顯示字符串,在屏幕最下方以黑底紅色顯示字符串
代碼如下:
1 assume cs:code, ds:data 2 3 data segment 4 str db 'try' 5 len equ $ - str 6 data ends 7 8 code segment 9 start: 10 mov ax,data 11 mov ds,ax 12 13 mov si,0 14 mov cx,len 15 mov bl,00000010b 16 mov bh,0 17 call printStr 18 19 mov si,0 20 mov cx,len 21 mov bl,00000100b 22 mov bh,24 23 call printStr 24 25 mov ah,4ch 26 int 21h 27 28 printStr: 29 mov ax,0b800h 30 mov es,ax 31 mov ax,0 32 mov al,bh 33 mov dx,160 34 mul dx 35 mov di,ax 36 s: mov al,ds:[si] 37 mov es:[di],al 38 inc si 39 inc di 40 mov es:[di],bl 41 inc di 42 loop s 43 ret 44 code ends 45 end start

實驗任務5
針對8086CPU,針對8086CPU,已知邏輯段定義如下:
1 data segment 2 stu_no db '20498329042' 3 len = $ - stu_no 4 data ends
在80×25彩色字符模式下,在屏幕最后一行正中間顯示學號。
要求輸出窗口藍底,學號和兩側折線,以 白色前景色顯示。
tips:
1. 80×25彩色字符模式顯示緩沖區結構,參見教材「實驗9 根據材料編程」里的說明。
2. 編寫程序實現時,將data段的學號換成自己的學號。
代碼如下:
1 assume cs:code, ds:data 2 3 data segment 4 stu_no db '201983290075' 5 len = $ - stu_no 6 data ends 7 8 code segment 9 start: 10 mov ax,data 11 mov ds,ax 12 13 mov ax, 0b800h 14 mov es, ax 15 mov di, 0 16 mov bl, 17h 17 mov cx, 80 * 25 18 19 s1: 20 mov al, ' ' 21 mov es:[di], al 22 inc di 23 mov es:[di], bl 24 inc di 25 loop s1 26 27 mov di, 160 * 24 28 mov cx, 34 29 s2: 30 mov al, '-' 31 mov es:[di], al 32 inc di 33 mov es:[di], bl 34 inc di 35 loop s2 36 37 mov di, 160 * 24 + 34 * 2 38 mov cx, 12 39 mov si, 0 40 s3: 41 mov al, [si] 42 mov es:[di], al 43 inc di 44 mov es:[di], bl 45 inc di 46 inc si 47 loop s3 48 49 mov di, 160 * 24 + 46 * 2 50 mov cx, 34 51 s4: 52 mov al, '-' 53 mov es:[di], al 54 inc di 55 mov es:[di], bl 56 inc di 57 loop s4 58 59 mov ax, 4c00h 60 int 21h 61 code ends 62 end start


浙公網安備 33010602011771號