先上代碼
assume cs:code, ds :data, ss:stack
:棧段
stack segment
db 100 dup(0)
stack ends
:數(shù)據(jù)段
data segment
db 100 dup(0)
string db 'Hello!$'
data ends
:代碼段
code segment
start:
mov ax, data
mov dx, ax
mov ax, stack
mov ss, ax
:調(diào)用函數(shù)
push word ptr offset string
call print
add sp, 2
push 1111h
push 2222h
call count
add sp, 4
push ax
call print
add sp, 2
mov ax, 4c00h
int 21h
count:
mov bp, sp
mov ax, ss:[bp+2]
mov bx, ss:[bp+4]
add ax, bx
ret
print:
mov bp, sp
mov dx, ss:[bp+2]
mov ah, 9h
int 21h
ret
code ends
end start
開(kāi)始分析
push word ptr offset string
將在數(shù)據(jù)段中的字符串Hello!的位置push到棧中($:代表結(jié)束,offset在數(shù)據(jù)段的偏移量
call print
會(huì)轉(zhuǎn)到print
同時(shí)會(huì)把下一條指令的偏移地址push到棧中
bp為基址寄存器,一般在函數(shù)中用來(lái)保存進(jìn)入函數(shù)時(shí)的sp的棧頂基址
sp是棧頂指針,它每次指向棧頂。
mov bp, sp
mov ax, ss:[bp+2]
mov bx, ss:[bp+4]
add ax, bx
ret
然后 ret會(huì)將ip指向到棧頂,也就是call push進(jìn)來(lái)的偏移地址(ip就是下一條處理的地址
默認(rèn)做法返回值會(huì)賦值給ax
為了保證棧平衡,調(diào)用完一個(gè)函數(shù)之后sp會(huì)加傳進(jìn)去的參數(shù)長(zhǎng)度
也就是將棧頂恢復(fù)到調(diào)用這個(gè)方法之前的位置

1585038202(1).png