jsonp跨域原理_回味經典之:那些年曾談起的跨域
阿新 • • 發佈:2020-12-11
實驗四
實驗任務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 ax,0b86eH mov es,ax mov bx,0 mov cx,3 s1: push cx mov cx,16 mov si,0 mov di,64 s: mov al,[si] mov es:[di],al mov al,[16+bx] mov es:[di+1],al 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
程式碼分析
- data段:
- 首先將字串'welcome to masm!'存入記憶體
- 再計算出要求的顏色(綠色、綠底紅色、白底藍色)對應的顏色屬性為
2,36,113
(10進位制)
- code段:
- 將data地址賦值給ds,用於將資料段資料存入指定記憶體地址
- 計算螢幕中間上一排對應的段地址為
0b86eh
,並將其賦值給額外資料段es mov bx,0
用bx標記當前輸出行數mov cx,0
需要輸出三行,因此外層迴圈為3次- 需要巢狀使用
loop指令
因此將當前cx壓入棧,並標記為s1 - 記憶體迴圈:共16個字元,因此迴圈16次
- 計算輸出到中間列的起始列偏移量為64,因此
mov di,64
,並將字元賦值到es:[di]
- 對應的顏色屬性為
[16+bx]
,將其賦值到es:[di+1]
- 一行輸出結束,進入下一行,將es+0ah
pop cx
進入下一迴圈
實驗任務2
任務內容
編寫子程式printStr,實現以指定顏色在螢幕上輸出字串。呼叫它,完成字串輸出。子程式printSar
功能:以指定顏色在螢幕上(從螢幕左上角開始)輸出字串
要求:字串以0結尾
入口引數
字串的起始地址—> ds: si (其中,字串所在段的段地址—> ds, 字串起始地址
的偏移地址—> si
字串顏色—> al
出口引數:無
程式碼
assume cs:code, ds:data data segment str db 'another try', 0 data ends code segment start: mov ax, data mov ds, ax mov si, offset str mov al, 4 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
輸出結果
程式碼分析
- 11行:
mov si,offset str
使用offset
指令,計算字串的偏移量 - 12行:
mov al,2
mov al,4
2、4分別為綠字和紅字的顏色屬性 - 13行:
call printStr
即跳轉至printStr
處 - 19-22行:將引數儲存,便於再次呼叫函式
- 26-29行:將字串存入cl,ch置0
- 若字元為0,即字串結束,則cx為0,則29行執行跳轉操作,跳轉至over處,恢復引數並返回
- 若字元不為0,則繼續執行下一語句
- 30行:將字元的顏色屬性存到記憶體單元的高地址
- 30-33行:輸出字元
實驗任務3
子任務1
任務內容
使用任意文字編輯器,錄入彙編源程式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
輸出結果
- 執行前:
- 執行後:
程式碼分析
- 9-12行:data段地址賦值到ds,1984(07c0h)賦值給x,str的偏移量賦值給di
- 18-46行:num2str函式
- 19-22行、41-44行,將引數儲存起來,便於二次呼叫函式
- cx指示位數,每除一次就+1,便於之後出棧儲存標明迴圈次數
- s1迴圈:
div bl
div指令將除數儲存在bl中,被除數在ax中(11行賦值),結果商在al中,餘數在ahpush dx
將餘數壓入棧cmp al,0
,若al==0,的zf=1jne s1
zf!=0,則跳轉到s1,以此實現迴圈除10,直到商為0,餘數入棧
- s2迴圈:
or dl 30h
將數字轉換為字元
子任務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
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 ax
push bx
push cx
push dx
mov bx, 0b800H
mov es, bx
mov di, 0
mov al,2
mov si,offset str
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 dx
pop cx
pop bx
pop ax
ret
code ends
end start
輸出結果
實驗任務4
任務內容
彙編、連結、執行程式,輸入一個字串並以#結束(比如,2020, bye#)觀察執行結果。結合執行結
果,理解程式功能,瞭解軟中斷指令。
程式碼
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
輸出結果
程式碼分析
- 12-19行:
mov ah,1; int 21h;
從鍵盤輸入,輸入結果存入al中cmp al,'#'
當al=='#'時,zf=1je next
當zf=1時,跳轉到next,即輸入結束,反正進入下一語句,繼續輸入
- 21-27行:
mov ah,2; mov dl,[si]; int 21h;
將[si]輸出到螢幕
- 即程式碼實現將鍵盤輸入的內容輸出
實驗任務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);
}
反彙編結果
反彙編分析
- 函式(包括main函式)在執行剛開始都有一段入棧操作,而在結束前又都有一段相對應的出棧操作,這應該是對函式呼叫棧的相關操作,用於結束函式時恢復現場
- 呼叫函式時,會先將引數從右往左壓入棧,以儲存引數
- 函式結果通過eax返回,main函式中,
mov dword ptr [c],eax
即說明這一點
總結
- 80×25彩色字元模式顯示緩衝區結構,通過這一結構,可以進行計算想要顯示在螢幕的位置對應的記憶體地址
- 將資料儲存到視訊記憶體對於地址的格式,低地址al存放字元,高地址ah存放顏色屬性
call
與ret
的結合使用,使用時在函式開始和結尾應當對暫存器資料進行入棧出棧操作,以避免對函式結束後造成影響- 數字的顯示方法,即實驗3已經對兩位數進行了討論,本實驗進一步通過
cmp
和jne
指令的結合使用實現了表示範圍內任意數字的輸出 - 通過對cpp程式的反彙編,更直接的認識了高階語言中程式的底層實現方式