在堆栈中创建命名变量

时间:2017-02-21 11:35:43

标签: assembly nasm fasm

有没有办法在堆栈中创建命名变量,而是通过offset来引用它们:

sub esp, 0x10 ; 4 variables of 4 bytes

mov DWORD [ebp-4], 0xf ; 1st var
mov DWORD [ebp-8], 0xff  ; 2nd var
; and so on

2 个答案:

答案 0 :(得分:8)

FASM

FASM通过FASM自带的ad-hoc制作宏支持局部变量。

include 'win32ax.inc' 

.code

  start:
        mov ax, 1

        call foo


  proc foo

      ;Local variables

      locals
        var1 dd ?
        var2 dw ?
      endl


      ;Use them as expected
      mov eax, [var1]
      lea ebx, [var2]

   ret
  endp 

编译 1 进入

:00401000 66B80100                mov ax, 0001
:00401004 E800000000              call 00401009
:00401009 55                      push ebp
:0040100A 89E5                    mov ebp, esp
:0040100C 83EC08                  sub esp, 00000008
:0040100F 8B45F8                  mov eax, dword ptr [ebp-08]
:00401012 8D5DFC                  lea ebx, dword ptr [ebp-04]
:00401015 C9                      leave
:00401016 C3                      ret

NASM

NASM也使用%local指令支持局部变量。

从手册中引用:

silly_swap: 
    %push mycontext             ; save the current context 
    %stacksize small            ; tell NASM to use bp 
    %assign %$localsize 0       ; see text for explanation 
    %local old_ax:word, old_dx:word 

    enter   %$localsize,0   ; see text for explanation 
    mov     [old_ax],ax     ; swap ax & bx 
    mov     [old_dx],dx     ; and swap dx & cx 
    mov     ax,bx 
    mov     dx,cx 
    mov     bx,[old_ax] 
    mov     cx,[old_dx] 
    leave                   ; restore old bp 
    ret                     ; 

    %pop                        ; restore original context
     

%$localsize变量由%local指令在内部使用,必须在当前上下文中定义,然后才能使用%local指令。

其他草率的方法

一个人可以

%define SUPER_VAR ebp-4
%define MEGA_VAR ebp-8

mov DWORD [SUPER_VAR], 0xf
mov DWORD [MEGA_VAR], 0xff

然而,这隐藏了变量在堆栈中并假设正确设置的帧指针的事实。

稍微好一点的方法:

%define SUPER_VAR 4
%define MEGA_VAR 8

mov DWORD [ebp-SUPER_VAR], 0xf
mov DWORD [ebp-MEGA_VAR], 0xff

汇编程序员方式

真正的汇编程序员使用注释 [citation needed] 来表明他们代码的意图。
并且仅在vi中编写代码。或者是emacs

mov DWORD [ebp-4], 0xf           ;SUPER_VAR
mov DWORD [ebp-8], 0xff          ;MEGA_VAR

汇编语言的主要优势在于其简单的语法和完整的信息方法(没有任何东西是隐藏的,程序员控制着一切)。

虽然使用高级宏 2 没有任何问题,但混合高级和低级方法会导致源文件难以为专家解析。

此外,从本体论的角度来看,它没有多大意义:如果你想使用高级功能,那么像C这样的语言更适合,必须重新考虑使用汇编。相反,如果你想学习如何进行低级编程,那么这些宏是学习过程的障碍。

最后,宏不是魔术。虽然很快就会很灵活,程序员会遇到他们的限制 例如,我没有挖掘对对齐局部变量的FASM和NASM支持。

1 此时此不再是装配......
2 高级宏允许您轻松地重构代码,这非常重要。人们应该暂停片刻,质疑自己在预期/需要进行重要重构时使用装配的选择。

答案 1 :(得分:0)

FASM本身的做法是通过jsfiddle指令:

对于论点:

.sidebar {
 height: calc(100% - 130px);
}

对于局部变量:

virtual at ebp + 8
  .arg1 dd ?
  .arg2 dq ?
end virtual

不同类型的virtual at ebp - 10h ; the offset is the size of the local variables area. .var1 dd ? .local_array rb 12 end virtual 宏在内部使用proc