1. 程式人生 > 實用技巧 >Qt 之初識Qt

Qt 之初識Qt

一、實驗內容
1、實驗任務1
使用任意文字編輯器,錄入彙編源程式task1.asm。

assume cs:code, ds:data
data segment
        db 'Nuist'
        db 5 dup(2)
data ends

code segment
start:
        mov ax, data
        mov ds, ax            ;ds儲存data資料段的段地址

        mov ax, 0b800H        ;b800段屬於視訊記憶體地址範圍
        mov es, ax            ;由暫存器es儲存

        mov cx, 
5 ;loop指令迴圈次數 mov si, 0         mov di, 0f00h ;視訊記憶體地址的段偏移量 s: mov al, [si] ;取data資料段第一段的位元組資料 and al, 0dfh ;轉大寫 mov es:[di], al ;將取出的資料存入到視訊記憶體地址中 mov al, [5+si] ;取data資料段第二段的位元組資料 mov es:[di+1], al ;存放,此次存放相對於同一次迴圈中的上次存放,是將資料放在了高位,用於修改輸出的內容的顏色 inc si ;偏移量加1 add di,
2 ;視訊記憶體的段地質偏移量增2 loop s ;實現跳轉 mov ah, 4ch int 21h code ends end start

閱讀源程式,從理論上分析原始碼的功能,尤其是line15-25,迴圈實現的功能是什麼,逐行理解每條指令的功能。
使用masm、link對task1.asm進行彙編、連結,得到可執行檔案task1.exe,執行並觀察結果。
使用debug工具對程式進行除錯,執行到程式返回前,即line27之前,觀察結果。
修改line4裡5個位元組單元的值,重新彙編、連結、執行,觀察結果。

db 5 dup(2)
--> 改成:
db 2,3,4,5,6

基於觀察,分析、猜測這裡的數值作用是什麼?

  程式碼功能:從理論上分析原始碼的功能是通過迴圈將data資料段中的字母轉換為大寫,同時修改顏色並在顯示器上輸出。(line15-25指令功能在程式碼註釋中給出)

1、使用masm、link對task1.asm進行彙編、連結,得到可執行檔案task1.exe,執行並觀察結果。

(1)、編譯、連線,如圖:

(2)、執行task1.exe檔案(在docbox中執行)

  執行結果中可以發先字串‘Nuist’被轉換為大寫,同時字型顏色為綠色顯示在doc命令視窗上,驗證了理論猜測。

2、使用debug工具對程式進行除錯,執行到程式返回前,即line27之前,觀察結果。

  檢視data資料段內容,如圖:資料段data中的主句如下

3、修改line4裡5個位元組單元的值,重新彙編、連結、執行,觀察結果。執行結果如圖:

  修改資料之後,執行結果發生變化,字元的顏色變化為五種不同的顏色。

4、使用debug工具除錯,檢視data段資料:

2、實驗任務2
已知資料段data中定義位元組資料如下:

data segments
db 23, 50, 66, 71, 35
data ends

編寫程式,在螢幕上以十進位制整數形式列印輸出這5個兩位數。

assume cs:code
data segment
    db 23, 50, 66, 71, 35
data ends

code segment
start:  
        mov ax, cs
        sub ax, 01h
        mov ds, ax            ;ds儲存data資料段的段地址
        mov dh, 10            ;作為除數
                    
        mov si, 0 
        mov cx, 5            ;迴圈次數
s:      mov ax, [si]        
        mov ah, 00h
        div dh                
        add al, 30h            ;商(低位)
        add ah, 30h            ;餘數(高位):數字與其ascii碼值差48(30H)
        mov bl, al
        mov bh, ah
        inc si                
        
        mov ah, 2
        mov dl, bl            ;輸出十位,bl是待輸出的字元,或其ASCⅡ碼值
        int 21h
        mov dl, bh            ;輸出個位    
        int 21h
        loop s                

        mov ah,4ch
        int 21h

code ends
end start

(1)、編譯、連線

(2)、使用debug工具除錯:

  1.進入debug,產看相關內容。

  2.使用g命令和t命令對程式進行除錯(以下為一次迴圈的過程)。

  3.執行程式(在docbox中執行)

3、實驗任務3
教材「實驗5 編寫、除錯具有多個段的程式」(1),程式原始碼參見task3.asm
將下面的程式編譯連結,後用debug載入,跟蹤,然後回答問題

;task3.asm
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h data ends stack segment dw
0, 0, 0, 0, 0, 0, 0, 0 stack ends code segment start: mov ax,stack mov ss, ax mov sp,16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends end start

①CPU執行程式,程式返回前,data資料段中的資料為多少?

  data段中的資料(0~f)為:23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09

②CPU執行程式,程式返回前,cs= ,ss= ,ds= 。

  cs,ss,ds暫存器的值:cs=0B68,ss=0B67,ds=0B66;

③設程式載入後,code段的段地址為X,則data段的地址為 ,stack段的段地址為 。

  data段的地址為 X - 2 ,stack段的段地址為 X-1 。

(1)對程式進行編譯、連線:

(2)使用debug工具除錯程式

  1.使用g命令執行程式到程式退出前:

  執行完g命令後可以檢視cs,ss,ds暫存器的值:cs=0B68,ss=0B67,ds=0B66;

在程式中

mov ax,stack  ;將stack的段地址傳遞給暫存器ss
mov ss, ax
     
mov ax, data  ;將data資料段的地址傳遞給暫存器ds
mov ds, ax

通過以上程式碼的功能可知到ss暫存器和ds暫存器的是分別是stack段和data段的段地址(程式執行到最後暫存器都未發生改變,資料段的內容少於16位元組),

由stack段、data段、程式碼段的段地址之間的關係可知道,若cs為X,則ss為X-1,ds為X-2;

  2.使用d指令檢視data段中的資料:

data段中的資料(0~f)為:23 01 56 04 89 07 BC 0A EF 0D ED 0F BA 0C 87 09。

4、實驗任務4
教材「實驗5 編寫、除錯具有多個段的程式」(2),程式原始碼見task4.asm。

將下面的程式編譯,連線,用debug載入、跟蹤,然後回答問題。

assume cs:code, ds:data, ss:stack
data segment
  dw 0123h, 0456h
data ends

stack segment
  dw 0, 0
stack ends

;task4.asm
code segment
start:  mov ax,stack
        mov ss, ax
        mov sp,16
        
        mov ax, data
        mov ds, ax
        
        push ds:[0]
        push ds:[2]
        pop ds:[2]
        pop ds:[0]
        
        mov ax,4c00h
        int 21h

code ends
end start

①CPU執行程式,程式返回前,data資料段中的資料為多少?

  data段中的資料(0~f)為:23 01 56 04 00 00 00 00 00 00 00 00 00 00 00 00

②CPU執行程式,程式返回前,cs= ,ss= ,ds= 。

  cs,ss,ds暫存器的值:cs=0B68,ss=0B67,ds=0B66;

③設程式載入後,code段的段地址為X,則data段的地址為 ,stack段的段地址為 。

  data段的地址為 X - 2 ,stack段的段地址為 X-1 。

④對於如下定義的段:

name segment
...
name ends

如果段中的資料佔N個位元組,則程式載入後,該段實際佔有的空間為:⌈N/16⌉*16位元組

(1)、對程式編譯、連線

(2)、使用debug工具除錯程式

  程式執行到退出前,檢視cs,ss,ds的值為:cs=0B68,ss=0B67 ,ds=0B66。

  檢視data段的資料

  前四個位元組為23 01 56 04 其餘均為0.

(3)、在程式中增加a段

a segment
    dw  0102h,3040h,0506h  ;共6個位元組
a ends

(因為name 的意思bai是模組定義偽操作,被系統徵用了name這個名字,使用name作為段名出錯)

  1.編譯連線後使用debug工具除錯:

  可發現增加一個段中後程序佔用的地址空間就增加10h個位元組

 2.使用的指令檢視data,stack以及a這三個資料段的值:

  修改as段的資料:dw 0102h, 0304h, 0506h,0102h, 0304h, 0506h,0102h, 0304h, 0506h,增加為9個字資料

 3.編譯連結後使用debug除錯,再次使用d查段中的資料:

 4.第二次修改:a段的資料修改位18個字資料(36位元組)

  編譯連結後使用debug除錯,再次使用d查段中的資料:

  檢視暫存器cx的值發先暫存器的值又增加了10h位元組

結論:從以上 結果可發現當段中的資料位元組數在十六個位元組(八個字資料)以內,該段佔用的空間都為十六位元組,

   當段中的資料大於16個位元組時(設為N)則佔用的地址空間為:⌈N/16⌉*16

5、實驗任務5
教材「實驗5 編寫、除錯具有多個段的程式」(3),程式原始碼見task5.asm。

將下面的程式編譯,連線,用debug載入、跟蹤,然後回答問題。

;task5.asm
assume cs:code, ds:data, ss:stack code segment start: mov ax,stack mov ss, ax mov sp,
16 mov ax, data mov ds, ax push ds:[0] push ds:[2] pop ds:[2] pop ds:[0] mov ax,4c00h int 21h code ends data segment dw 0123h, 0456h data ends stack segment dw 0,0 stack ends end start

①CPU執行程式,程式返回前,data資料段中的資料為多少?

  data段中的資料(0~f)為:23 01 56 0400 00 00 00 00 00 00 00 00 00 00 00

②CPU執行程式,程式返回前,cs= ,ss= ,ds= 。

  cs,ss,ds暫存器的值:cs=0B68,ss=0B67,ds=0B66;

③設程式載入後,code段的段地址為X,則data段的地址為 ,stack段的段地址為 。

  通過debug除錯發現程式碼段佔用30h個位元組,data段的地址為 X + 3 ,stack段的段地址為 X+ 4 。

(1)、對程式編譯、連線

(2)、使用debug工具除錯程式

  使用g命令執行到程式返回前:從中可檢視:cs=0B66,ss=0B6A,ds=0B69.

  使用d指令檢視data資料段中的資料:23 01 56 0400 00 00 00 00 00 00 00 00 00 00 00

6、實驗任務6
教材「實驗5 編寫、除錯具有多個段的程式」(4)

如果將(1)、(2)、(3)題中的最後一條偽指令”end start“改為”end“也就是說不知名程式的入口),則哪個程式任然可以正確執行?請說明理由。

(1)修改task3.asm中的偽指令,編譯、連線後使用debug指令進行除錯:

進行以下操作之後發先task3.asm修改之後不能正確彙編,也不能正確執行。

(2)修改task4.asm中的偽指令,編譯、連線後使用debug指令進行除錯:

結果與task3.asm相同,修改後不能正確彙編,也不能正確執行。

(3)修改task5.asm中的偽指令,編譯、連線後使用debug指令進行除錯:

  修改過後,只有task5.asm問件在編譯連結之後才能進行正確的反彙編,cs暫存器的值才是指令所在段的正確段地址值。

(4)、對比task3.asm、task4.asm、task5.asm三個檔案在各個段的內容:

cs的值存放的是儲存所有段 的段地址,task3和task4都是指令在最後,而task5是指令在最前(第一段)所以在task5中cs的值就是指令所在段的段地址,

只有task5.asm在修改後程式仍然能夠執行。

7、 實驗任務7
教材「實驗5 編寫、除錯具有多個段的程式」(5)
程式原始碼見task7.asm。
注*: 如果在整合軟體環境下編寫、彙編這個實驗任務,請將段名為c的邏輯段,名稱改為c1或別的標識
符。由於早期一些指令集中使用c指代暫存器,如不更正,有些彙編器在彙編時會報錯。

程式如下:編寫code段中的程式碼,將a段和b段中的資料依次相加結果存到c段中,

assume cs:code
a segment
  db 1,2,3,4,5,6,7,8
a ends

b segment
  db 1,2,3,4,5,6,7,8
b ends

c segment            ; 在整合軟體環境中,請將此處的段名稱由c→改為c1或其它名稱
  db 8 dup(0)
c ends

code segment
start:
    mov ax,cs
    sub ax,0003h
    mov ds,ax

    mov ax,0000h
    mov bx,0000h

    mov cx,4
 s:    mov ax,[bx]
     mov dx,[bx+10h]
     add ax,dx
    mov [bx+20h],ax
    add bx,2
    loop s

    mov ax,4c00h
    int 21h
code ends
end start

(1)、對程式編譯、連線

(2)、使用dubug除錯檢視程式結果:

檢視c段的內容,a段和b段的值一次相加的結果正確存放到了c段中。

8、實驗任務8
教材「實驗5 編寫、除錯具有多個段的程式」(6),程式原始碼見task8.asm。
程式如下:編寫code段中的程式碼,用push指令將a段中前8個字型資料逆序儲存到c段中。

assume cs:code
a segment
  dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
a ends

b segment
  dw 8 dup(0)
b ends

code segment
start: 
    mov ax,cs
    sub ax,1
    mov ss,ax
    mov sp,0010h
    sub ax,2
    mov ds,ax

    mov bx,0000h

    mov cx,8
s:    mov ax,[bx]
    push ax
    add bx,2
    loop s
    
    mov ax,4c00h
    int 21h
code ends
end start

(1)、對程式進行編譯、連線

(2)、使用debug工具對車光緒進行除錯,並檢視結果: