1. 程式人生 > 實用技巧 >PHP 呼叫執行外網介面

PHP 呼叫執行外網介面

一、實驗目的

1、理解和掌握將資料、程式碼、棧放入不同邏輯段的程式的編寫和除錯

2、理解具有多個段的彙編源程式對應的目標程式執行時,記憶體分配方式

3、掌握大小寫字元的轉換方法、數字字元和數值之間的轉換方法

4、理解並掌握各種定址方式的靈活應用

5、掌握彙編指令loop,and,or,div,mul的用法

二、實驗準備

複習教材chapter6-8章

chapter 6包含多個段的程式

chapter 7更靈活的定位記憶體地址的方法

chapter 8資料處理的兩個基本問題

三、實驗內容及結論

1、實驗任務1

使用任意文字編輯器,錄入彙編源程式task1.asm。

 1 assume cs:
code, ds:data 2 data segment 3 db 'Nuist' 4 db 5 dup(2) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 12 mov ax, 0b800H 13 mov es, ax 14 15 mov cx, 5 16 mov si, 0 17 mov di, 0f00h 18 s: mov al, [si] 19 and al, 0dfh 20 mov es:[di], al
21 mov al, [5+si] 22 mov es:[di+1], al 23 inc si 24 add di, 2 25 loop s 26 27 mov ah, 4ch 28 int 21h 29 code ends 30 end start

閱讀源程式,從理論上分析原始碼的功能,尤其是line15-25,循壞實現的功能是什麼,逐行理解每條指令的功能。

使用masm、link對task1.asm進行彙編、連線,得到可執行檔案task1.exe,執行結果如下:

使用debug工具對程式進行除錯,執行到程式返回前,即line27之前,得到如下結果:

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

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

修改後的程式碼執行結果如下:

基於觀察,分析、猜測原始碼中data段line4的位元組資料的用途是什麼?

對比執行結果可以看出,修改後程式執行結果的後3個字母的顏色發生了改變,所以line4中的位元組資料應該是用於控制字元的顏色的。

2、實驗任務2

已知資料段data中定義位元組資料如下:

1 data segments
2     db 23, 50, 66, 71, 35
3 data ends

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

 1 assume cs:code, ds:data
 2 data segment
 3     db 23, 50, 66, 71, 35
 4 data ends
 5 
 6 code segment
 7 start:
 8     mov ax,data
 9     mov ds,ax
10 
11     mov si,0
12     mov cx,5
13 
14 s:  mov ah,0
15     mov al,ds:[si]
16     mov bl,10
17     div bl
18     mov ds:[16+si],al
19     mov ds:[17+si],ah
20 
21     mov ah,2
22     mov dl,ds:[16+si]
23     add dl,48
24     int 21h
25 
26     mov ah,2
27     mov dl,ds:[17+si]
28     add dl,48
29     int 21h
30 
31     mov ah,2
32     mov dl,32
33     int 21h
34     
35     inc si
36     loop s
37 
38     mov ax,4c00h
39     int 21h
40 code ends
41 end start

彙編、連線之後的執行結果如下:

3、實驗任務3

教材[實驗5 編寫、除錯具有多個段的程式](1)

原始碼:

 1 assume cs:code, ds:data, ss:stack
 2 data segment
 3   dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
 4 data ends
 5 
 6 stack segment
 7   dw 0, 0, 0, 0, 0, 0, 0, 0
 8 stack ends
 9 
10 code segment
11 start:  mov ax,stack
12         mov ss, ax
13         mov sp,16
14         
15         mov ax, data
16         mov ds, ax
17         
18         push ds:[0]
19         push ds:[2]
20         pop ds:[2]
21         pop ds:[0]
22         
23         mov ax,4c00h
24         int 21h
25 
26 code ends
27 end start

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

data段的資料沒有發生改變。

②CPU執行程式,程式返回前,cs=076C,ss=076B,ds=076A

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

把上面的程式進行彙編、連線,並用debug工具進行除錯:

將源程式進行反彙編,並使用g命令將程式執行到程式返回前,此時可以看到CS=076C,SS=076B,DS=076A。再用d命令檢視data段中的資料,發現data段中的資料沒有發生變化。

4、實驗任務4

教材[實驗5 編寫、除錯具有多個段的程式](2)

源程式:
 1 assume cs:code, ds:data, ss:stack
 2 data segment
 3   dw 0123h, 0456h
 4 data ends
 5 
 6 stack segment
 7   dw 0, 0
 8 stack ends
 9 
10 code segment
11 start:  mov ax,stack
12         mov ss, ax
13         mov sp,16
14         
15         mov ax, data
16         mov ds, ax
17         
18         push ds:[0]
19         push ds:[2]
20         pop ds:[2]
21         pop ds:[0]
22         
23         mov ax,4c00h
24         int 21h
25 
26 code ends
27 end start

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

data段的前4個位元組的資料沒變,後面的資料都是0。

②CPU執行程式,程式返回前,cs=076C,ss=076B,ds= 076A

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

④對於如下定義的段:
name segment
…
name ends

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

一個段佔有的實際空間總是16位元組的整數倍,所以公式為段中資料的位元組數除以16的向上取整,再乘以16。

將源程式彙編、連線以後,用debug工具進行除錯。反彙編以後,用g命令執行到程式返回前,此時可以看到cs、ss和ds的值;再用d命令檢視data段的資料,發現前4個位元組的資料為data段中給出的數值,後面12個位元組都為0,所以data段的實際佔用空間還是16個位元組。

5、實驗任務5

教材[實驗5 編寫、除錯具有多個段的程式](3)

源程式:

 1 assume cs:code, ds:data, ss:stack
 2 
 3 code segment
 4 start:  mov ax,stack
 5         mov ss, ax
 6         mov sp,16
 7         
 8         mov ax, data
 9         mov ds, ax
10         
11         push ds:[0]
12         push ds:[2]
13         pop ds:[2]
14         pop ds:[0]
15         
16         mov ax,4c00h
17         int 21h
18 
19 code ends
20 data segment
21   dw 0123h, 0456h
22 data ends
23 
24 stack segment
25   dw 0,0
26 stack ends
27 end start

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

data段中的前4個位元組的資料為程式碼中已給出的值,其餘都是0。

②CPU執行程式,程式返回前,cs=076A ,ss=076E ,ds= 076D

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

將源程式彙編、連線以後,用debug工具進行除錯。反彙編以後,用g命令執行到程式返回前,此時可以看到cs、ss和ds的值;再用d命令檢視data段的資料:

6、實驗任務6

教材[實驗5 編寫、除錯具有多個段的程式](4)

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

分別將task3.asm、task4.asm及task5.asm中的最後一條偽指令“end start”改為“end”,重新彙編、連線,並用debug工具進行反彙編:

從上面的結果可以看出,3個程式在彙編、連線時都沒有報錯,但前兩個程式反彙編之後,得到的是一些雜亂的指令,只有第3個程式的反彙編結果與原來相同,且能夠正確執行。

源程式最後一條偽指令“end start”實際上是指明瞭程式的入口,可執行檔案被載入到記憶體中後,CPU的CS:IP被設定指向這個入口,從而開始執行程式中的第一條指令。又因為標號“start”在“code”段中,所以CPU就會將code段中的內容當做指令來執行。

將源程式最後一條偽指令“end start”改為“end"之後,當可執行檔案被載入到記憶體中時,就會自動將程式的首地址當做程式的入口。所以對於task3.asm和task4.asm來說,CS:IP指向了資料的首地址,資料段被反彙編以後,得到是雜亂的指令,無法正確執行。而task5.asm之所以能正確執行,只因為源程式將程式碼段放在了程式的開始,將資料段和棧段放在了後面,所以CS:IP仍是指向程式碼段的地址。

7、實驗任務7

教材[實驗5 編寫、除錯具有多個段的程式](5)

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

源程式:

 1 assume cs:code
 2 a segment
 3   db 1,2,3,4,5,6,7,8
 4 a ends
 5 
 6 b segment
 7   db 1,2,3,4,5,6,7,8
 8 b ends
 9 
10 c segment   
11   db 8 dup(0)
12 c ends
13 
14 code segment
15 start:
16     mov ax,a
17     mov ds,ax
18 
19     sub bx,bx
20     mov cx,8
21 
22 s:  mov ax,ds:[bx]
23     add ax,ds:[bx+16]
24     mov ds:[bx+32],ax
25     inc bx
26     loop s
27 
28     mov ax,4c00h
29     int 21h
30 code ends
31 end start

將以上源程式進行彙編、連線,並用debug工具進行除錯。將程式反彙編之後,用g命令執行到程式返回之前:

然後用d命令檢視資料段a、b、c中的內容,發現邏輯段c中的資料正好是邏輯段a和邏輯段b中對應資料的和,說明該程式編寫正確。

8、實驗任務8

教材[實驗5 編寫、除錯具有多個段的程式](6)

編寫code段中的程式碼,用push指令將a段中的前8個字型資料,逆序儲存到b段中。

源程式:

 1 assume cs:code
 2 a segment
 3   dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh
 4 a ends
 5 
 6 b segment
 7   dw 8 dup(0)
 8 b ends
 9 
10 code segment
11 start: 
12     mov ax,a
13     mov ds,ax
14 
15     mov ax,b
16     mov ss,ax
17     mov sp,16
18 
19     sub bx,bx
20     mov cx,8
21 
22 s:  push ds:[bx]
23     add bx,2
24     loop s
25 
26     mov ax,4c00h
27     int 21h
28 code ends
29 end start

將上面的源程式彙編、連線,並用debug工具除錯,用u命令將源程式反彙編:

用g命令執行到程式返回之前,此時用d命令檢視邏輯段b中的資料,發現邏輯段b中存放得是8到1,說明程式編寫正確: