python連線資料庫之(連線MySQL)
四、實驗結論
1、實驗任務1
程式設計:在螢幕中間分別顯示綠色、綠底紅色、白底藍色的字串'welcome to masm!'。
1 assume cs:code,ds:data 2 data segment 3 db 'welcome to masm!' 4 data ends 5 6 code segment 7 start: mov ax,data 8 mov ds,ax 9 mov ax,0b800h 10 mov es,ax 11 mov bx,0720h ;0720h=(160×12)+(80-16)=1760+64=1824 第12行64列的地址12 mov si,0 13 14 mov cx,16 ;'welcome to masm!'一共16個字元 15 s:mov ax,[si] 16 mov ah,2h ;0000 0020b 背景色黑色,前景色綠色 17 mov es:[bx],ax ;把第一行綠色字型寫入視訊記憶體 18 mov ah,24h ;0010 0100b 背景色綠色,前景色紅色 19 mov es:[bx+0a0h],ax ;把第二行寫入視訊記憶體,一行字元佔用160個位元組,80×2=160=a0h 20 mov ah,71h ;0111 0001b 背景色白色,前景色藍色 21 mov es:[bx+0a0h+0a0h],ax ;把第三行寫入視訊記憶體 偏移量:160+160=a0h+a0h 22 23 inc si ;指向下一字元 24 add bx,2 ;指向下一視訊記憶體單元 25 loop s 26 27 mov ah,4ch 28 int 21h29 code ends 30 end start
80×25的彩色字元模式,即一屏25行80列。 每一行顯示一個字元需要兩個位元組(低位位元組存放字元的ASCⅡ碼值,高位位元組存放字元的顯示 屬性),一共160個位元組。
將源程式編譯、連線、執行,結果如下:
2、實驗任務2
編寫子程式printStr,實現以指定顏色在螢幕上輸出字串。呼叫它,完成字串輸出。
子程式printSar
- 功能:以指定顏色在螢幕上(從螢幕左上角開始)輸出字串
- 要求:字串以0結尾
- 入口引數
字串的起始地址—> ds: si (其中,字串所在段的段地址—> ds, 字串起始地址 的偏移地址—> si
字串顏色—> al
- 出口引數:無
1 assume cs:code, ds:data 2 data segment 3 str db 'try', 0 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 11 mov si, offset str 12 mov al, 2 13 call printStr 14 15 mov ah, 4ch 16 int 21h 17 18 printStr: 19 push bx 20 push cx 21 push si 22 push di 23 24 mov bx, 0b800H 25 mov es, bx 26 mov di, 0 27 s: mov cl, [si] 28 mov ch, 0 29 jcxz over 30 mov ch, al 31 mov es:[di], cx 32 inc si 33 add di, 2 34 jmp s 35 36 over: pop di 37 pop si 38 pop cx 39 pop bx 40 ret 41 42 code ends 43 end start
執行結果截圖:
對源程式做如下修改:
把line3改為:
1 str db 'another try', 0
把line12改為:
1 mov al, 4 ;0000 0100 前景色紅色
再次彙編、執行程式,觀察執行結果。
- line19-22, line36-39,這組對稱使用的push、pop,這樣用的目的是什麼?
使用棧機制,儲存現場,子程式將會使用到這四個暫存器di、si、cx、bx,防止與主程式中可能用到的暫存器發生衝突,壓入棧中暫存資料。等到子程式執行完成,再從棧中彈出。
- line30的功能是什麼?
將暫存器cx的中資料寫入到視訊記憶體 段地址為 b8000h,偏移量為 di 的記憶體單元。
其中 ch 存放字元的顯示屬性,cl 存放字元的ASCⅡ碼值。
3、實驗任務3
使用任意文字編輯器,錄入彙編源程式task3.asm。
子程式num2str:
- 功能:把0~2559之間的任意整數轉換成數字字串,例如,把1984轉換成'1984'
- 入口引數
要轉換的整數 —> ax
數字字串的起始地址 —> ds:di (其中:數字字串所在段的段地址—> ds,字串 起始地址的偏移地址—>di)
- 出口引數:無
- 子任務1
對task_3.asm進行彙編、連結,得到可執行程式後,在debug中使用u命令反彙編,使用g命令執行 到line15(程式退出之前),使用d命令檢視資料段內容,觀察是否把轉換後的數字字串'1984'存放 在資料段中str標號後面的單元。
經檢視,轉換後的數字字元‘1984’已成功存放在str標號後面的單元。
- 子任務2
1 assume cs:code, ds:data 2 data segment 3 x dw 1984 4 str db 16 dup(0) 5 data ends 6 7 code segment 8 start: mov ax, data 9 mov ds, ax 10 mov ax, x 11 mov di, offset str 12 call num2str 13 14 mov si, offset str 15 mov al, 4 16 call printStr 17 18 mov ah, 4ch 19 int 21h 20 21 num2str: 22 push ax 23 push bx 24 push cx 25 push dx 26 27 mov cx, 0 28 mov bl, 10 29 s1: 30 div bl 31 inc cx 32 mov dl, ah 33 push dx 34 mov ah, 0 35 cmp al, 0 36 jne s1 37 s2: 38 pop dx 39 or dl, 30h 40 mov [di], dl 41 inc di 42 loop s2 43 44 pop dx 45 pop cx 46 pop bx 47 pop ax 48 49 ret 50 printStr: 51 push bx 52 push cx 53 push si 54 push di 55 56 mov bx, 0b800H 57 mov es, bx 58 mov di, 0 59 s: mov cl, [si] 60 mov ch, 0 61 jcxz over ;判斷是否是字元結尾 62 mov ch, al 63 mov es:[di], cx ;寫入視訊記憶體 64 inc si ;指向下一個字元 65 add di, 2 ;指向下一個視訊記憶體 66 jmp s 67 68 over: pop di 69 pop si 70 pop cx 71 pop bx 72 ret 73 74 code ends 75 end start
彙編、執行程式,結果如下。
將line3中的數值改成成0~2559之間的任意數值,執行測試,觀察結果。
4、實驗任務4
使用任意文字編輯器,錄入彙編源程式task4.asm。
1 assume cs:code, ds:data 2 data segment 3 str db 80 dup(?) 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 mov si, 0 11 12 s1: 13 mov ah, 1 14 int 21h 15 mov [si], al 16 cmp al, '#' 17 je next 18 inc si 19 jmp s1 20 next: 21 mov cx, si 22 mov si, 0 23 s2: mov ah, 2 24 mov dl, [si] 25 int 21h 26 inc si 27 loop s2 28 29 mov ah, 4ch 30 int 21h 31 code ends 32 end start
ine12-19實現的功能是?
呼叫int 21h中的1號子功能,從鍵盤輸入單個字元。若果讀到 ‘#’ 就結束輸入,跳轉到標號為next 的程式碼段,否則一直迴圈輸入,並將字元儲存在ds:[si]所在記憶體單元。
line21-27實現的功能是?
呼叫int 21h中的2號子功能,在螢幕上輸出單個字元。將儲存在ds:[si]輸入的字元一一輸出在螢幕上。
5、實驗任務5
在visual studio整合環境中,編寫一個簡單的包含有函式呼叫的c程式。程式碼如下:
1 #include <stdio.h> 2 int sum(int, int); 3 4 int main() { 5 int a = 2, b = 7, c; 6 7 c = sum(a, b); 8 9 return 0; 10 } 11 12 int sum(int x, int y) { 13 return (x + y); 14 }
在line7, line13分別設定斷點,在除錯模式下,檢視反彙編程式碼。 分析反彙編程式碼,從彙編的角度,觀察高階語言中引數傳遞和返回值是通過什麼實現的,以及,引數入棧順序,返回值的帶回方式,等等。
主程式裡用call指令呼叫子程式,在子程式裡是用ret指令返回。
呼叫函式時:形參入棧自右向左,就上述程式,先將引數b的值存入eax,並將eax入棧,再將引數a的值存入ecx,並將ecx入棧。返回結果存在暫存器eax中。
五、實驗總結
- 1、理解80×25彩色字元模式顯示原理
- 2、int 21h中的1號子功能
功能:從鍵盤輸入單個字元
用法:mov ah, 1
int 21h ; 出口引數為al, 從鍵盤輸入的字元儲存在al中
- 3、函式引數傳遞方式
函式呼叫規則指的是呼叫者和被呼叫函式間傳遞引數及返回引數的方法,在Windows上,常用的有Pascal方式、WINAPI方式(_stdcall)、C方式(_cdecl)。
A、_cdecl C呼叫規則:
(a)引數從右到左進入堆疊;
(b)在函式返回後,呼叫者要負責清除堆疊,這種呼叫方式通常會生成較大的可執行程式。
B、_stdcall又稱為WINAPI,呼叫規則如下:
(a)引數從右到左進入堆疊;
(b)被呼叫的函式在返回前自行清理堆疊,這種方式生成的程式碼比cdecl小。
C、Pascal呼叫規則(主要用於Win16函式庫中,現在基本不用):
(a)引數從左到右進入堆疊;
(b)被呼叫的函式在返回前自行清理堆疊。
(c)不支援可變引數的函式呼叫。