簡體   English   中英

與push功能相同的指令序列

[英]Instruction sequence that does the same thing as push

我想知道是否有可能(如果可以,如何)編寫一系列與push具有相同效果的指令。 例如,如果ax的內容為1200,而我執行了a push ax ,那么我還可以使用其他哪些指令來完成a push ax呢?

其他一些答案使用[sp]進行堆棧尋址,但是在16位模式或32位或64位模式下都不可能。 但是,在32位模式下,可以使用[esp] ;在x86-64中,可以將[rsp]用於內存尋址,但是在16位模式下,沒有使用sp內存尋址。 有關16位模式下可能的存儲器尋址模式,請參見此處

因此,您需要做的是:將bp的值存儲在某個地方,將sp復制到bp ,然后使用bp尋址堆棧,最后恢復bp的原始值。

如果您有存儲bp的地方,那很簡單(這是YASM / NASM語法):

mov [bp_storage], bp
sub sp,2
mov bp,sp
mov [bp],ax
mov bp,[bp_storage]

...

bp_storage dw 0

在這里使用寄存器而不是像bp_storage這樣的內存地址也很簡單。

編輯:添加了不修改標志的版本(如下所示),因為push也不修改標志。

上面的代碼修改了標志,而push ax並沒有修改任何標志。 這可以通過存儲第一要解決ah到存儲器中,然后加載標志成ahlahf ,然后從存儲的標志ah到存儲器,那么修改所述堆如上述,然后之后從存儲器經由恢復標志ah通過使用sahf最后恢復從內存ah

編輯:要模擬沒有更改標志的push ax ,必須在lahf之前保存lahf並在mov [bp],ax之前加載ah 固定。

mov [ah_storage],ah
lahf
mov [flags_storage],ah
mov [bp_storage],bp
sub sp,2
mov bp,sp
mov ah,[ah_storage]
mov [bp],ax
mov bp,[bp_storage]
mov ah,[flags_storage]
sahf
mov ah,[ah_storage]

...

bp_storage    dw 0
ah_storage    db 0
flags_storage db 0

sub修改AFCFOFPFSFZF ,而lahf加載和sahf僅存儲AFCFPFSFZF (無OF )。 但是, sp絕不會在正常堆棧使用中溢出。

但是,如果您無法訪問內存,並且希望使用堆棧來存儲bp ,則可以執行此操作,但是如果您都沒有可用的免費寄存器,那么事情將會變得復雜。 但是,如果您使用的是實模式操作系統,則可以使用cli阻止中斷,交換bpsp ,使用bp進行堆棧尋址,再次交換bpsp ,並再次使用sti允許中斷。

編輯: sp的值需要減去2以模擬push ax 固定。 此版本不修改標志(中斷標志除外)。

cli
xchg bp,sp
lea bp,[bp-2]
mov [bp],ax
xchg bp,sp
sti

至少如果有內存,它大致相當於:

sub sp, 2
mov [sp], ax

減去一個等於sp所需數據寫入大小的值,然后在堆棧上移動/寫入所需的對象。 編譯器一直在做這種事情。 查看-S輸出示例。 如果執行此操作,請當心原子/線程問題...

如果我沒有忘記英特爾語法:

lea sp, [sp-2]
mov [sp], ax

我用lea避免接觸FLAGS (既不push也不是movlea觸摸它們,但subdec做)。

編輯:原來,我已經忘記了更重要的事情:沒有[sp]尋址模式。 正確答案是@nrz給出的答案,我的答案可以應用於80386及更高版本上的espeax (將為lea esp,[esp-4] )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM