有没有办法在堆栈中创建命名变量,而是通过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
答案 0 :(得分:8)
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也使用%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
。