centos7安裝配置mysql8
組合語言實驗四
實驗任務1
在螢幕中間分別顯示綠色、綠底紅色、白底藍色的字串'welcome to masm'
task1.asm:
assume cs:code,ds:data data segment db 'welcome to masm!' data ends code segment start:mov ax,data mov ds,ax mov ax,0b800h mov es,ax mov cx,16 mov bx,0 mov di,11*160+64;顯示視訊記憶體中的偏移量,11行64位元組的列偏移量 s1:mov al,ds:[bx] mov ah,00000010b;設定顏色 mov es:[di],ax;設定數值 inc bx add di,2 loop s1 mov cx,16 mov bx,0 mov di,12*160+64 s2:mov al,ds:[bx] mov ah,00100100B mov es:[di],ax inc bx add di,2 loop s2 mov cx,16 mov bx,0 mov di,13*160+64 s3:mov al,ds:[bx] mov ah,01110001B mov es:[di],ax inc bx add di,2 loop s3 code ends end start
實驗結果:
實驗任務2
編寫子程式printStr,實現以指定顏色在螢幕上輸出字串、呼叫它完成字串輸出:
task2.asm:
assume cs:code, ds:data data segment str db 'try', 0 data ends code segment start: mov ax, data mov ds, ax mov si, offset str mov al, 2 call printStr mov ah, 4ch int 21h printStr: push bx push cx push si push di mov bx, 0b800H mov es, bx mov di, 0 s: mov cl, [si] mov ch, 0 jcxz over mov ch, al mov es:[di], cx inc si add di, 2 jmp s over: pop di pop si pop cx pop bx ret code ends end start
實驗結果:
將line3改成:
str db 'another try',0
line 12改成:
mov al,4
結果:
基於執行結果,理解原始碼,以及,組合使用轉移指令call和ret實現子程式的原理與方法。具體地,在 line18-40中:
-
line19-22, line36-39,這組對稱使用的push、pop,這樣用的目的是什麼?
-
- line 19-22是為了防止暫存器在子程式和主程式起衝突而設定的,以便在主程式中恢復原先的暫存器中的內容;line36-39就是暫存器內容恢復的過程
-
line30的功能是什麼?
-
- line30是像實驗1中的一樣,將分別表示顏色和數值的cx送入視訊記憶體空間之中,以便顯示出來;
實驗任務3
使用任意文字編輯器,錄入彙編源程式task3.asm;
子程式num2str:
- 功能:把0~2559之間的任意整數轉換成數字字串,例如,把1984轉換成'1984'
- 入口引數 要轉換的整數 —> ax
- 數字字串的起始地址 —> ds:di (其中:數字字串所在段的段地址—> ds,字串 起始地址的偏移地址—>di)
- 出口引數:無
程式碼:
assume cs:code, ds:data
data segment
x dw 1984
str db 16 dup(0)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, x
mov di, offset str
call num2str
mov si, offset str
call printStr
mov ah, 4ch
int 21h
num2str:
push ax
push bx
push cx
push dx
mov cx, 0
mov bl, 10
s1:
div bl
inc cx
mov dl, ah
push dx
mov ah, 0
cmp al, 0
jne s1
s2:
pop dx
or dl, 30h
mov [di], dl
inc di
loop s2
pop dx
pop cx
pop bx
pop ax
ret
printStr:
push bx
push cx
push si
push di
mov bx, 0b800H
mov es, bx
mov di, 0
s: mov cl, [si]
mov ch, 0
jcxz over
mov ch, al
mov es:[di], cx
inc si
add di, 2
jmp s
over: pop di
pop si
pop cx
pop bx
ret
code ends
end start
子任務1
對task3.asm進行彙編、連結,得到可執行程式後,在debug中使用u命令反彙編,使用g命令執行 到line15(程式退出之前),使用d命令檢視資料段內容,觀察是否把轉換後的數字字串'1984'存放 在資料段中str標號後面的單元。
debug結果如下:
子任務2
對task3.asm原始碼進行修改、完善,把task2.asm中用於輸出以0結尾的字串的子程式加進來, 實現對轉換後的字串進行輸出。
程式碼:
assume cs:code, ds:data
data segment
x dw 1984
str db 16 dup(0)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov ax, x
mov di, offset str
call num2str
mov si, offset str
call printStr
mov ah, 4ch
int 21h
num2str:
push ax
push bx
push cx
push dx
mov cx, 0
mov bl, 10
s1:
div bl
inc cx
mov dl, ah
push dx
mov ah, 0
cmp al, 0
jne s1
s2:
pop dx
or dl, 30h
mov [di], dl
inc di
loop s2
pop dx
pop cx
pop bx
pop ax
ret
printStr:
push bx
push cx
push si
push di
mov bx, 0b800H
mov es, bx
mov di, 11*160+64
s: mov cl, [si]
mov ch, 0
jcxz over
mov ch, al
mov es:[di], cx
inc si
add di, 2
jmp s
over: pop di
pop si
pop cx
pop bx
ret
code ends
end start
效果:
修改line3的值效果:
可以看出顏色是由暫存器al中的資料所控制;
實驗任務4
使用任意文字編輯器,錄入彙編源程式task4.asm。
程式碼:
assume cs:code, ds:data
data segment
str db 80 dup(?)
data ends
code segment
start:
mov ax, data
mov ds, ax
mov si, 0
s1:
mov ah, 1
int 21h
mov [si], al
cmp al, '#'
je next
inc si
jmp s1
next:
mov cx, si
mov si, 0
s2: mov ah, 2
mov dl, [si]
int 21h
inc si
loop s2
mov ah, 4ch
int 21h
code ends
end start
效果截圖:
line12-19行的作用是:讀入字元,直到遇見#為止;
line21-27實現的作用是:輸出從鍵盤輸入的字串;
實驗任務5
在visual studio整合環境中,編寫一個簡單的包含有函式呼叫的c程式。程式碼如下:
#include<stdio.h>
int sum(int, int);
int main()
{
int a=2,b=7,c;
c=sum(a,b);
return 0;
}
int sum(int x,int y)
{
return (x+y);
}
在line7, line13分別設定斷點,在除錯模式下,檢視反彙編程式碼。
分析反彙編程式碼,從彙編的角度,觀察高階語言中引數傳遞和返回值是通過什麼實現的,以及,引數入 棧順序,返回值的帶回方式,等等。
從上面的彙編程式碼我們可以看到,在函式的入口,將[b]和[a]中的值先後push進棧中,然後通過call命令跳轉到sum函式處。待函式完成後通過mov指令,將eax賦值給[c]完成函式運算。
int sum到return (x+y)的反彙編程式碼我們可以看出,顯示將重要的暫存器入棧保護,return操作就是將[x]的值加到[y]中去,然後暫存器出棧進行暫存器恢復,然後ret返回主函式,完成運算。
實驗結論
- 本次實驗使我瞭解了此程式的編寫過程,以及8086中80*25彩色模式的顯示原理。
- 能夠熟練的使用jmp、loop、jcxz等跳轉指令,根據跳轉的不同原理完成各項功能。
- 能夠綜合使用ret、call、je、jz、cmp等指令完成綜合的子程式,迴圈分支結構程式碼的編寫。
- 通過對c語言的返彙編實驗,將彙編與高階語言結合起來,更加加深了對組合語言的理解。