集合運算在資料庫中的應用
一、實驗目的
1. 理解和掌握將資料、程式碼、棧放入不同邏輯段的程式的編寫和除錯
2. 理解具有多個段的彙編源程式對應的目標程式執行時,記憶體分配方式
3. 掌握大小寫字元的轉換方法、數字字元和數值之間的轉換方法
4. 理解並掌握各種定址方式的靈活應用 5. 掌握彙編指令loop, and, or,div, mul的用法
二、實驗準備
複習教材chapter 6-8章。
chapter 6 包含多個段的程式
chapter 7 更靈活的定位記憶體地址的方法
chapter 8 資料處理的兩個基本問題
三.實驗內容
實驗任務1:
將以下程式碼寫入文字編輯器:
assume cs:code, ds:data data segment db 'Nuist' db 5 dup(2) data ends code segment start: mov ax, data mov ds, ax mov ax, 0b800H mov es, ax mov cx, 5 mov si, 0 mov di, 0f00h s: mov al, [si] and al, 0dfh mov es:[di], al mov al, [5+si] mov es:[di+1], al inc si add di, 2 loop s mov ah, 4ch int 21h code ends end start
閱讀源程式,從理論上分析原始碼的功能,尤其是line15-25,迴圈實現的功能是什麼,逐行理解每條指 令的功能。
解:首先分析程式,第一步先初始化di,si,然後設定cx值為5,進行5次迴圈,然後將五個字母轉化成大寫後寫入視訊記憶體,然後利用高位字元控制在視訊記憶體輸出字元的顏色,然後再在視訊記憶體輸出低位字元NUIST,這裡的and做的是轉化字元為大寫,數字段中的5個2則是將字元顏色變為綠色。
然後進行編譯,連結,執行得到結果如下:
執行:
然後修改 dp 5 dup(2)為dp 2,3,4,5,6,結果如下:
從此實驗中可以看出,高位字元代表視訊記憶體低位輸出字元的顏色。
實驗任務2:
已知資料段data中定義位元組資料如下:
data segments db 23, 50, 66, 71, 35 data ends
編寫程式,在螢幕上以十進位制整數形式列印輸出這5個兩位數。
編寫程式碼如下:
assume cs:code, ds:data data segment db 23,50,66,71,35 data ends code segment start: mov ax, data mov ds, ax mov di,0 mov cx,5 s: mov ah,0 mov al,ds:[di] mov bl,10 div bl mov ds:[di+10],al mov ds:[di+11],ah mov ah,2 mov dl, ds:[di+10] add dl,30h int 21h mov ah,2 mov dl, ds:[di+11] add dl,30h int 21h mov ah,2 mov dl, " " int 21h inc di loop s mov ah, 4ch int 21h code ends end start
經過編譯,連結,執行得到如下結果:
實驗任務3:
將下面的程式編譯、連結、用debug載入、跟蹤,然後回答問題:
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
經過編譯,連結
使用debug檢視:
1.cpu執行程式,程式返回前,data段中的資料為多少?
資料可以看到為 0123 0456 0789 0ABC 0DEF 0FED 0CBA 0987
2.CPU執行程式,程式返回前,cs=076C ss=076B ds=076A
3.已知code地址段段地址為X,那麼data段段地址為?stack段段地址為?
data段段地址為X-2,stack段段地址為X-1
實驗任務4:
將下面的程式編譯、連結、用debug載入、跟蹤,然後回答問題:
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h data ends stack segment dw 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
經過編譯,連結:
1.cpu執行程式,程式返回前,data段中的資料為多少?
資料可以看到為 0123 0456
2.CPU執行程式,程式返回前,cs=076C ss=076B ds=076A
3.已知code地址段段地址為X,那麼data段段地址為?stack段段地址為?
data段段地址為X-2,stack段段地址為X-1
4.對於如下定義的段
name segment
...
name ends
如果段中的資料佔N個位元組,那麼程式載入後,該段實際佔有空間為:
可以綜合實驗3和實驗4,得到佔用空間為 (int(N/16)+1)*16
實驗任務5:
將下面的程式編譯、連結、用debug載入、跟蹤,然後回答問題:
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
編譯,連結,執行:
然後debug:
1.cpu執行程式,程式返回前,data段中的資料為多少?
資料可以看到為 0123 0456
2.CPU執行程式,程式返回前,cs=076A ss=076E ds=076D
3.已知code地址段段地址為X,那麼data段段地址為?stack段段地址為?
data段段地址為X+3,stack段段地址為X+4
實驗任務6:
將前面那幾題中的最後一條偽指令”end start“改為”end“,哪個程式可以正確執行?
第三個,因為程式碼段定義在資料段和棧段之前,如果要反彙編資料段和棧段,也可以正確執行程式碼,不會改變程式開始的位置,所以可以正常的結束程式,另外兩個都在程式碼段之前,所以需要先反彙編,那麼就一定會改變程式碼段起始位置,無法執行。
實驗任務7:
編寫code段中的程式碼,將a段和b段中的資料依次相加,將結果存到c1段中。
程式碼如下:
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 c1 segment ; 在整合軟體環境中,請將此處的段名稱由c→改為c1或其它名稱 db 8 dup(0) c1 ends code segment start: mov bx,0 mov cx,8 s: mov si,a mov ds,si mov al,ds:[bx] mov si,b mov ds,si add al,ds:[bx] mov si,c1 mov ds,si mov ds:[bx],al inc bx loop s mov ax,4c00h int 21h code ends end start
編譯,連結,debug如下:
可以看到C段結果如下:
實驗任務8:
編寫code段中的程式碼,用push指令將a段中的前8個字型資料,逆序儲存到b段中。
程式碼如下:
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 bx,0
mov cx,8
mov si,a
mov ds,si
s: push ds:[bx]
add bx,2
loop s
mov bx,0
mov si,b
mov cx,8
mov ds,si
c: pop ds:[bx]
add bx,2
loop c
mov ah,4ch
int 21h
code ends
end start
debug:
因為是dw雙位元組資料,所以每次bx要加2,可以看到1--8共8個數都已經全部逆序輸入到b段中。
四.實驗總結
在本次實驗中,我瞭解了記憶體中段的具體含義,段地址就代表了記憶體中某段地址用於儲存資料,同時需要弄清楚段中資料的具體所佔空間大小,同時要注意的是資料段的儲存,弄清楚資料儲存中的位元組大小,至少佔用16個位元組,同時避免程式碼執行混亂,一定要加上end start,否則容易混淆,導致程式碼無法正確執行。此外,還有使用div除法時,需要注意ah儲存商,al儲存餘數,同時在寫程式碼時要注意迴圈的位置,同時要注意使用bx和數字段b的時候不要混淆,會導致程式碼異常中斷。