如何通过 call 和 ret 更改堆栈内容?
how to change stack content with call and ret?
这段代码模拟了图灵机。我正在检测这段代码,我对更改的每一步都做了 table 没关系,但我不明白如何使用 CALL AND RET [=11 更改堆栈内容=]
.model small
.data
bant db 0,0,0,0,0,0,0,0,0
.code
.startup
mov si,4
call stateA
.exit
stateA proc near
cmp bant[si],0
je AB
jmp AC
AB:
mov bant[si],1
inc si
call stateB
jmp RTA
AC:
mov bant[si],1
dec si
call stateC
RTA: ret
stateA endp
stateB proc near
cmp bant[si],0
je BA
jmp BB
BA:
mov bant[si],1
dec si
call stateA
jmp RTB
BB:
mov bant[si],1
inc si
call stateB
RTB: ret
stateB endp
stateC proc near
cmp bant[si],0
je CB
jmp CHLT
CB:
mov bant[si],1
dec si
call stateB
jmp RTC
CHLT:
mov bant[si],1
inc si
RTC: ret
stateC endp
end
RET 不写入栈,但是它修改了SP。 CALL 将 return 地址写入堆栈,并修改 SP。
您可以写入堆栈的唯一值是 CALL 之后指令的 IP,因此我认为使用 just CALL 和RET 指令。
您可能需要使用 MOV 指令和其他指令以正常方式执行此操作。通常使用相对于 [BP]
的寻址模式,在创建堆栈帧后。
如何在堆栈顶部加载某个值的偏移量有一个巧妙的技巧:
call print_message ; address of string is pushed on top of stack
db "some text message to print",0 ; defined inside code
print_message:
call some_print_function ; which want single argument on stack as "ptr to string"
; restore stack as needed (but don't do "ret", it would execute string)
但这很可能在 32b 模式下使用得更多,因为推送的偏移量在代码段内 cs
,因此在 16b 实模式下,这仅适用于包含所有内容的代码单段和 cs = ds
。例如,大多数“.com”可执行文件都符合此描述。
如果您的代码使用更多段,则必须以通过 cs:
寻址该字符串的方式编写该打印例程,这并不常见。
这段代码模拟了图灵机。我正在检测这段代码,我对更改的每一步都做了 table 没关系,但我不明白如何使用 CALL AND RET [=11 更改堆栈内容=]
.model small
.data
bant db 0,0,0,0,0,0,0,0,0
.code
.startup
mov si,4
call stateA
.exit
stateA proc near
cmp bant[si],0
je AB
jmp AC
AB:
mov bant[si],1
inc si
call stateB
jmp RTA
AC:
mov bant[si],1
dec si
call stateC
RTA: ret
stateA endp
stateB proc near
cmp bant[si],0
je BA
jmp BB
BA:
mov bant[si],1
dec si
call stateA
jmp RTB
BB:
mov bant[si],1
inc si
call stateB
RTB: ret
stateB endp
stateC proc near
cmp bant[si],0
je CB
jmp CHLT
CB:
mov bant[si],1
dec si
call stateB
jmp RTC
CHLT:
mov bant[si],1
inc si
RTC: ret
stateC endp
end
RET 不写入栈,但是它修改了SP。 CALL 将 return 地址写入堆栈,并修改 SP。
您可以写入堆栈的唯一值是 CALL 之后指令的 IP,因此我认为使用 just CALL 和RET 指令。
您可能需要使用 MOV 指令和其他指令以正常方式执行此操作。通常使用相对于 [BP]
的寻址模式,在创建堆栈帧后。
如何在堆栈顶部加载某个值的偏移量有一个巧妙的技巧:
call print_message ; address of string is pushed on top of stack
db "some text message to print",0 ; defined inside code
print_message:
call some_print_function ; which want single argument on stack as "ptr to string"
; restore stack as needed (but don't do "ret", it would execute string)
但这很可能在 32b 模式下使用得更多,因为推送的偏移量在代码段内 cs
,因此在 16b 实模式下,这仅适用于包含所有内容的代码单段和 cs = ds
。例如,大多数“.com”可执行文件都符合此描述。
如果您的代码使用更多段,则必须以通过 cs:
寻址该字符串的方式编写该打印例程,这并不常见。