5.call和ret指令
call和ret指令使用:
assume cs:code, ds:data, ss:stack
; 棧段
stack segment
db 100 dup(0)
stack ends
; 資料段
data segment
db 100 dup(0)
string db 'Hello!$'
data ends
; 程式碼段
code segment
start:
; 手動設定ds、ss的值
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
; 業務邏輯
call print
mov ax, 1122h
mov bx, 3344h
add ax, bx
; 退出
mov ax, 4c00h
int 21h
; 列印字串
print:
; ds:dx告知字串地址
mov dx, offset string
mov ah, 9h
int 21h
ret
code ends
end start
; 函式的要素
; 1.引數
; 2.返回值
; 3.區域性變數
實現函式返回值:
demo1:使用ds
assume cs:code ,ds:data ss:stack
data segment
db 100 dup(0)
data ends
code segment
start:
mov ax,data
mov ds,ax
call returnFunc
mov bx,[0]
returnFunc :
mov ax,2
add ax,ax
mov [0],ax
ret
code ends
end start
demo2:使用ds中的別名
...
data segment
;定義別名result
result dw 0
data ends
...
start:
mov ax,data
mov ds,ax
call returnFunc
mov bx,result
...
returnFunc :
mov ax,2
add ax,ax
mov result,ax
ret
demo3:通用做法是返回值直接放在ax通用暫存器中
實現函式傳參:
1.使用ax暫存器儲存引數來實現傳遞
2.使用棧來儲存引數來傳遞,也是通用做法:
- 使用bp來快速訪問棧中資料
- 使用mov sp指令來快速釋放棧中資料
assume cs:code, ds:data, ss:stack
; 棧段
stack segment
db 100 dup(0)
stack ends
; 資料段
data segment
db 100 dup(0)
data ends
; 程式碼段
code segment
start:
; 手動設定ds、ss的值
mov ax, data
mov ds, ax
mov ax, stack
mov ss, ax
; 業務邏輯
push 1122h
push 3344h
call sum3
add sp, 4
push 2222h
push 2222h
call sum3
add sp, 4
; 退出
mov ax, 4c00h
int 21h
; 返回值放ax暫存器
; 傳遞2個引數(放入棧中)
sum3:
; 訪問棧中的引數
mov bp, sp
mov ax, ss:[bp+2]
add ax, ss:[bp+4]
ret
; 返回值放ax暫存器
; 傳遞2個引數(分別放ds:0、ds:2)
sum2:
mov ax, [0]
add ax, [2]
ret
; 返回值放ax暫存器
; 傳遞2個引數(分別放cx、dx中)
sum1:
mov ax, cx
add ax, dx
ret
code ends
end start
; 棧平衡:函式呼叫前後的棧頂指標要一致
; 棧如果不平衡的結果:棧空間遲早會被用完
注意區分遞迴呼叫、函式內呼叫函式和連續呼叫多個函式對棧的使用的區別,
函式內呼叫函式會一直往棧中壓資料,而多函式連續呼叫,只會當前函式棧中資料釋放後再繼續下一個函式的壓棧操作。
棧平衡的方法:
1.外平棧,函式外面進行平棧,也就是上面的操作,要是常用的做法
2.內平棧,函式內進行平棧,函式內呼叫其他函式的時候:
sum2:
mov ax, [0]
add ax, [2]
call sum1
ret
sum1:
mov ax, cx
add ax, dx
ret 4
相關文章
- 組合語言-CALL和RET指令組合語言
- ret2shellcode
- 【PWN】Ret2libc
- pwn學習-ret2libc
- ret2csu出題小記
- [新手向]ret2dl-resolve詳解
- ora-600 [rwoirw: check ret val] with count distinct and order by
- 【Linux】find指令和grep指令!!!Linux
- 64位ret hat linux 5.5安裝小記Linux
- 關於pwn題的棧平衡中ret的作用
- DOCKERFILE的CMD指令和ENTRYPOINT指令Docker
- 08 指令和程式
- Oracle 10.2.0.5 emca配置報錯-ssl Open wallet failed, ret = 28750OracleAI
- include,forward和param指令Forward
- vue指令和特殊特性Vue
- Exploit開發系列教程-Exploitme1 (“ret eip” overwrite) &More space on stack
- Dbconsole Fails To Start With Nzos_handshake Failed,Ret=29024AI
- 比較forward動作指令和include動作指令Forward
- RouterOS 限速指令碼和限執行緒指令碼ROS指令碼執行緒
- Dockerfile CMD和ENTRYPOINT指令Docker
- Dockerfile ADD和COPY指令Docker
- include指令和include動作
- ciscn_2019_c_1(型別:ret2libc)型別
- lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)
- Django的下載和基本指令Django
- 操作符offset 和 jmp指令
- 如何區分資料和指令
- RMAN的基本知識和指令
- 『現學現忘』Docker基礎 — 38、COPY指令和ADD指令Docker
- 精簡指令集和複雜指令集的區別
- 主題 2 Shell工具和指令碼指令碼
- 建庫和表的指令碼.sql指令碼SQL
- Unix命令列程式和內建指令命令列
- ORACLE DBA常用語句和指令碼Oracle指令碼
- ORACLE分析表和索引的指令碼Oracle索引指令碼
- shell和bash指令碼命令學習指令碼
- 分享一例指令碼發版和tomcat重啟指令碼指令碼Tomcat
- shell動態指令碼和pl/sql動態指令碼的比較指令碼SQL