将变量直接推送到堆栈的问题

时间:2016-04-14 17:27:40

标签: assembly stack

我目前的代码有效,如下:

movzx  ecx, var1
lea    eax, var2

push eax             
push ecx             

call func1

//...

和func1是:

push ebp           
mov ebp, esp       

mov ecx, [ebp + 8] 
mov eax, [ebp + 12]

push edi           
push ecx           

not byte ptr[eax] 

//... 

但是,我希望直接推送var2的地址,同时简单地按下var1的值,但是我无法弄清楚如何:

push var1            
push var2 //address of)

call func1

非常感谢任何和所有帮助。

3 个答案:

答案 0 :(得分:2)

好吧,如果字节变量var1在内存中有一个DWORD空间(4字节)并且是零扩展的,那么你可以只PUSH它。如果LEA的地址位于var2'段中的固定地址,则可以替换var2的{​​{1}}。像这样:

.data

在这些条件下,您的要求很容易满足。

答案 1 :(得分:1)

无法获取寄存器值的地址。

但是,您可以做两件事:

如果值在psuedo寄存器var2中并且是通过你的程序的操作创建的(即,不是系统调用返回寄存器等),可以简单地执行以下操作,而不是mov var2, [avar2]

mov var2, avar2

如果这不适合您,您可以将var2推送到堆栈并从esp获取地址,例如

push var2
lea avar2, [esp-4]

答案 2 :(得分:0)

使用编译器EMU8086,您可以执行此操作。接下来是你的代码有一些变化(我使用16位寄存器,这就是BP + 4和BP + 6的原因):

.stack 100h
.data  
var1 dw 25              ;VAR1 = 25.
var2 dw 800             ;VAR2 = 800.
.code
  mov  ax, @data
  mov  ds, ax

  push var1             ;PUSH 25.
  push offset var2      ;PUSH ADDRESS OF 800.
  call func1

  mov  ax, 4c00h 
  int  21h              ;FINISH.

func1 proc
  push bp
  mov  bp, sp
  mov  si, [ bp + 4 ]   ;POP ADDRESS OF 800.
  mov  ax, [ bp + 6 ]   ;POP 25.  

  not  [ byte ptr si ]  ;CX CANNOT BE USED AS POINTER.

  pop  bp
  ret
func1 endp

地址800被提取到SI而不是CX,因为CX不能用于指向地址。

请记住堆栈中的内容是颠倒存储的:首先推送25,然后推送地址800,这就是为什么地址位于BP + 4的位置以及BP + 6中的25位。