1. 程式人生 > 實用技巧 >基於CentOS 7.9環境部署MySQL 8.0服務

基於CentOS 7.9環境部署MySQL 8.0服務

一、實驗目的

1. 理解80×25彩色字元模式顯示原理

2. 理解轉移指令jmp, loop, jcxz的跳轉原理,掌握使用其實現分支和迴圈的用法

3. 理解轉移指令call, ret, retf的跳轉原理,掌握組合使用call和ret/retf編寫彙編子程式的方法,掌握 引數傳遞方式

4. 理解標誌暫存器的作用

5. 理解條件轉移指令je, jz, ja, jb, jg, jl等的跳轉原理,掌握組合使用匯編指令cmp和條件轉移指令實 現分支和迴圈的用法

6. 瞭解在visual studio/Xcode等環境或利用gcc命令列引數反彙編c語言程式的方法,理解編譯器生成 的反彙編程式碼

7. 綜合應用定址方式和彙編指令完成應用程式設計

二、實驗準備

實驗前,請複習/學習教材以下內容:

第9章 轉移指令的原理

第10章 call和ret指令

第11章 標誌暫存器

三、實驗內容

1. 實驗任務1 教材「實驗9 根據材料程式設計」(P187-189)

程式設計:在螢幕中間分別顯示綠色、綠底紅色、白底藍色的字串'welcome to masm!'。

程式碼:

assume cs:code
data segment
  db 'welcome to masm!'
  db 2,36,113          ;分別對應示綠色、綠底紅色、白底藍色
data ends
code segment
start:
        mov ax,data
        
mov ds,ax mov bx,0b872H mov es,bx mov cx,3 ;設定外層迴圈次數 mov bx,0 ;記錄當前輸出的行數 s1: push cx ;雙層迴圈利用棧 mov cx,16 ;根據輸出的字元長度確定內層迴圈的次數 mov di,0 mov si,0 s: mov al,[si] ;存放內容資訊 mov es:[di],al mov ah,[16
+bx] ;存放顏色資訊 mov es:[di+1],ah inc si add di,2 loop s inc bx mov ax,es ;換行 add ax,0ah mov es,ax pop cx loop s1 mov ax,4c00h int 21h code ends end start

80×25的彩色字元模式,即一屏25行80列。要輸出在螢幕中央並且輸出三行,應該從第十一行開始輸出,第十一行的偏移地址為1760(十進位制),需要輸出在中央,所以字元也應當水平居中,要輸出的字元佔32位元組(包括顏色屬性)。一行160位元組,(160-32)/2=64,64+1760=1824,對應的十六進位制為720h,所以視訊記憶體中的段地址為B872h。

2. 實驗任務2

編寫子程式printStr,實現以指定顏色在螢幕上輸出字串。呼叫它,完成字串輸出。

子程式printSar 功能:

以指定顏色在螢幕上(從螢幕左上角開始)輸出字串

要求:字串以0結尾

入口引數 字串的起始地址—> ds: si

其中,字串所在段的段地址—> ds, 字串起始地址 的偏移地址—> si

字串顏色—> al 出口引數:無

使用任意文字編輯器,錄入彙編源程式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

把line12改為:mov al, 4

再次彙編、執行程式,觀察執行結果。

基於執行結果,理解原始碼,以及,組合使用轉移指令call和ret實現子程式的原理與方法。具體地,在 line18-40中:

line19-22, line36-39,這組對稱使用的push、pop,這樣用的目的是什麼? line30的功能是什麼?

修改後執行結果:

對稱使用push,pop的目的是暫存暫存器的內容防止程式執行時修改內容無法恢復。line30的目的是將字元和顏色屬性送入視訊記憶體中。

3. 實驗任務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 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
code ends
end start

閱讀原始碼,理解子程式num2str的彙編實現。

子任務1

對task3.asm進行彙編、連結,得到可執行程式後,在debug中使用u命令反彙編,使用g命令執行 到line15(程式退出之前),使用d命令檢視資料段內容,觀察是否把轉換後的數字字串'1984'存放 在資料段中str標號後面的單元。

檢察是否把轉換後的數字字串'1984'存放 在資料段中str標號後面的單元:

子任務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
        mov al, 2
        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

執行截圖:

改變line3的值為2020:

4. 實驗任務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

彙編、連結、執行程式,輸入一個字串並以#結束(比如,2020, bye#)觀察執行結果。

結合執行結 果,理解程式功能,瞭解軟中斷指令。

具體地: line12-19實現的功能是? line21-27實現的功能是?

執行結果:

line12-19實現的功能是呼叫int21 1號子功能從鍵盤讀入字元,若字元不等於#則繼續讀入,若字元等於#則停止讀入執行next程式碼段。

line21-27實現的功能是呼叫int21 2號子功能在螢幕上輸出第一次輸入的內容。

5. 實驗任務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分別設定斷點,在除錯模式下,檢視反彙編程式碼。

分析反彙編程式碼,從彙編的角度,觀察高階語言中引數傳遞和返回值是通過什麼實現的,以及,引數入 棧順序,返回值的帶回方式,等等。

設定斷點:

反彙編程式碼:

#include <stdio.h>
int sum(int, int);
int main() {
00F217B0  push        ebp  
00F217B1  mov         ebp,esp  
00F217B3  sub         esp,0E4h  
00F217B9  push        ebx  
00F217BA  push        esi  
00F217BB  push        edi  
00F217BC  lea         edi,[ebp-0E4h]  
00F217C2  mov         ecx,39h  
00F217C7  mov         eax,0CCCCCCCCh  
00F217CC  rep stos    dword ptr es:[edi]  
00F217CE  mov         ecx,offset _D0D8FC35_源@cpp (0F2C003h)  
00F217D3  call        @__CheckForDebuggerJustMyCode@4 (0F2130Ch)  
    int a = 2, b = 7, c;
00F217D8  mov         dword ptr [a],2  
00F217DF  mov         dword ptr [b],7  
    c = sum(a, b);
00F217E6  mov         eax,dword ptr [b]  
00F217E9  push        eax  
00F217EA  mov         ecx,dword ptr [a]  
00F217ED  push        ecx  
00F217EE  call        sum (0F2116Dh)  
00F217F3  add         esp,8  
00F217F6  mov         dword ptr [c],eax  
    return 0;
00F217F9  xor         eax,eax  
}
00F217FB  pop         edi  
00F217FC  pop         esi  
00F217FD  pop         ebx  
00F217FE  add         esp,0E4h  
00F21804  cmp         ebp,esp  
00F21806  call        __RTC_CheckEsp (0F21235h)  
00F2180B  mov         esp,ebp  
00F2180D  pop         ebp  
00F2180E  ret  
int sum(int x, int y) {
00F21740  push        ebp  
00F21741  mov         ebp,esp  
00F21743  sub         esp,0C0h  
00F21749  push        ebx  
00F2174A  push        esi  
00F2174B  push        edi  
00F2174C  lea         edi,[ebp-0C0h]  
00F21752  mov         ecx,30h  
00F21757  mov         eax,0CCCCCCCCh  
00F2175C  rep stos    dword ptr es:[edi]  
00F2175E  mov         ecx,offset _D0D8FC35_源@cpp (0F2C003h)  
00F21763  call        @__CheckForDebuggerJustMyCode@4 (0F2130Ch)  
    return (x + y);
00F21768  mov         eax,dword ptr [x]  
00F2176B  add         eax,dword ptr [y]  
}
00F2176E  pop         edi  
00F2176F  pop         esi  
00F21770  pop         ebx  
00F21771  add         esp,0C0h  
00F21777  cmp         ebp,esp  
00F21779  call        __RTC_CheckEsp (0F21235h)  
00F2177E  mov         esp,ebp  
00F21780  pop         ebp  
00F21781  ret  

引數傳遞的方式是先將引數存入暫存器,再從右向左壓入棧中,通過call命令呼叫函式,執行加法後將結果存入儲存器最後返回主函式。