1. 實驗任務1
assume cs:code, ds:data data segment x db 1, 9, 3 len1 equ $ - x ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是3 y dw 1, 9, 3 len2 equ $ - y ; 符號常量, $指下一個資料項的偏移地址,這個示例中,是9 data ends code segment start: mov ax, data mov ds, ax mov si, offset x ; 取符號x對應的偏移地址0 -> si mov cx, len1 ; 從符號x開始的連續位元組資料項個數 -> cx 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 ; 取符號y對應的偏移地址3 -> si mov cx, len2/2 ; 從符號y開始的連續字資料項個數 -> cx 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
① line27, 彙編指令 loop s1 跳轉時,是根據位移量跳轉的。通過debug反彙編,檢視其機器碼, 分析其跳轉的位移量是多少?(位移量數值以十進位制數值回答)從CPU的角度,說明是如何計算得 到跳轉後標號s1其後指令的偏移地址的。
F2H=[11110010]補=[10001110]原=-14O
-14O=(D-19-2)H
② line44,彙編指令 loop s2 跳轉時,是根據位移量跳轉的。通過debug反彙編,檢視其機器碼, 分析其跳轉的位移量是多少?(位移量數值以十進位制數值回答)從CPU的角度,說明是如何計算得 到跳轉後標號s2其後指令的偏移地址的。
F0H=[11110000]補=[10010000]原=-16O
-16O=[29-37-2]H
2. 實驗任務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
① 根據call指令的跳轉原理,先從理論上分析,程式執行到退出(line31)之前,暫存器(ax) = ? 暫存器 (bx) = ? 暫存器(cx) = ?
ax=0021
執行call word ptr ds:[0]時,先把當前的IP存起來,當前IP指向下一條命令,地址為0021,於是0021入棧
接著執行POP AX,將棧頂的內容彈出,儲存至AX,於是AX的值就是0021
bx=0026
執行call dword ptr ds:[2]時,因為dword(雙字),IP指向下一條指令的地址為076C:0026.於是0026先入棧,然後076C再入棧
接著執行POP BX,將棧頂的內容彈出,儲存至BX,棧頂為0026,於是BX的值就是0026
cx=076C
接著執行POP CX,將棧頂的內容彈出,儲存至CX,棧頂為076C,於是CX的值就是076C
3. 實驗任務3
編寫8086彙編源程式task3.asm,在螢幕上以十進位制形式輸出data段中這一組連續的資料,資料和資料 之間以空格間隔。 要求: 編寫子程式printNumber 功能:以十進位制形式輸出一個兩位數 入口引數:暫存器ax(待輸出的資料 --> ax) 出口引數:無 編寫子程式printSpace 功能:列印一個空格 入口引數:無 出口引數:無 在主體程式碼中,綜合應用定址方式和迴圈,呼叫printNumber和printSpace, 實現題目要求。
assume cs:code, ds:data data segment x db 99, 72, 85, 63, 89, 97, 55 len equ $ - x data ends code segment main: mov ax, data mov ds, ax mov si, offset x mov cx, len s1: mov ah, 0 mov al, [si] call printNumber ;輸出十進位制數字 call printSpace ;輸出空格 inc si loop s1 mov ax, 4c00h int 21h printNumber: mov bl, 10 div bl ;將兩位數分開來輸出,先模10,獲得十位數,al放商,ah放餘數,預設除數為ax mov bx, ax mov dl, bl or dl, 30h ;將數字轉變成字元 mov ah, 2 ;顯示字元(商) int 21h mov dl, bh or dl, 30h mov ah, 2 ; ;顯示字元(餘數) int 21h ret printSpace: mov dl, ' ' mov ah, 2 int 21h ret code ends end main
4. 實驗任務4
編寫子程式printStr 功能:在指定行、以指定顏色,在螢幕上顯示字串 入口引數 字串首字元地址 --> ds:si(其中,字串所在段的段地址—> ds, 字串起始地址的偏 移地址—> si) 字串長度 --> cx 字串顏色 --> bl 指定行 --> bh (取值:0 ~24) 出口引數:無 ; 功能:輸出單個字元 mov ah, 2 mov dl, ×× ; ××是待輸出的字元,或其ASCⅡ碼值 int 21h 1 2 3 4 5 data segment str db 'try' len equ $ - str data ends 1 2 3 4 在主體程式碼中,兩次呼叫printStr,使得在螢幕最上方以黑底綠字顯示字串,在螢幕最下方以黑 底紅色顯示字串
assume ds:data, cs:code data segment str db 'try' len equ $ - str data ends code segment start: mov ax,data mov ds,ax mov si,0 mov cx,len;字串長度為len賦值給cx mov bh,0 ;綠色字元顯示在第0行 mov bl,02h;綠色 call printStr mov si,0 mov cx,len;字串長度為len賦值給cx mov bh,24 ;紅色字元顯示在第24行 mov bl,04h;紅色 call printStr mov ax,4c00h int 21h printStr: mov ax,0b800h ;80*25字元緩衝區 mov es,ax mov al,bh mov bh,0a0h ;一行是160個位元組,即a0h總共偏移24行,即偏移地址為24*160個位元組 mul bh ;mul預設al和mul後面的暫存器相乘,結果放在ax中 mov bp,ax s: mov ah,ds:[si];每次取出一個位元組給ah mov es:[bp],ah;把字母存給視訊記憶體地址低八位中 inc bp mov es:[bp],bl;將顏色資訊存入高八位 inc bp inc si loop s ret code ends end start
5. 實驗任務5
在80×25彩色字元模式下,在螢幕最後一行正中間顯示學號。要求輸出視窗藍底,學號和兩側折線,以 白色前景色顯示。 注*: 1. 80×25彩色字元模式顯示緩衝區結構,參見教材「實驗9 根據材料程式設計」裡的說明。 2. 編寫程式實現時,將data段的學號換成自己的學號。
assume ds:data, cs:code data segment stu_no db '201983290384' len = $ - stu_no data ends code segment start: mov ax,data mov ds,ax mov si,0 mov cx,07D0h; mov bh,0 mov bl,00010111B ;對應藍底白字 call printblankspace mov si,0 mov cx,004Fh; mov bh,24 ;字元顯示在第24行 mov bl,00010111B;對應藍底白字 call printline mov si,0 mov cx,len ;字串長度為len賦值給cx mov bh,24 ;綠色字元顯示在第24行 mov bl,00010111B;對應藍底白字 call printstr mov ax,4c00h int 21h printstr: mov ax,0b800h ;80*25字元緩衝區 mov es,ax mov al,bh mov bh,0a0h ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組 mul bh ;mul預設al和mul後面的暫存器相乘,結果放在ax中 add ax,3ch mov bp,ax ;160/2-12/2=74 s: mov ah,ds:[si];每次取出一個位元組給ah mov es:[bp],ah;把字母存給視訊記憶體地址低八位中 inc bp mov es:[bp],bl;將顏色資訊存入高八位 inc bp inc si loop s ret printline: mov ax,0b800h ;80*25字元緩衝區 mov es,ax mov al,bh mov bh,0a0h ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組 mul bh mov bp,ax s1: mov ah,'-';每次取出一個位元組給ah mov es:[bp],ah;把字母存給視訊記憶體地址低八位中 inc bp mov es:[bp],bl;將顏色資訊存入高八位 inc bp inc si loop s1 ret printblankspace: mov ax,0b800h ;80*25字元緩衝區 mov es,ax mov al,bh mov bh,0a0h ;一行是160個位元組,即a0.總共偏移24行,即24*160個位元組 mul bh ;mul預設al和mul後面的暫存器相乘,結果放在ax中 mov bp,ax ;bp為顯示字串開始的位置 s2: mov ah,' ' ;每次取出一個位元組給ah mov es:[bp],ah;把字母存給視訊記憶體地址低八位中 inc bp mov es:[bp],bl ;將顏色資訊存入高八位 inc bp inc si loop s2 ret code ends end start