Assembly 在堆栈中创建命名变量
有没有办法在堆栈中创建命名变量,而不是通过偏移量引用它们:Assembly 在堆栈中创建命名变量,assembly,nasm,fasm,Assembly,Nasm,Fasm,有没有办法在堆栈中创建命名变量,而不是通过偏移量引用它们: 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 FASM FASM通过FASM本身附带的特制特殊宏来支持局部变量 include 'win32ax.inc' .code start: mov ax, 1
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
FASM
FASM通过FASM本身附带的特制特殊宏来支持局部变量
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
它被编译成
纳斯姆
NASM使用指令也支持局部变量
从手册中引用:
%$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
汇编编程方式
真正的汇编程序程序员使用注释来说明他们代码的意图。
并且只在
vi
中编写代码。或者它是emacs
mov DWORD [ebp-4], 0xf ;SUPER_VAR
mov DWORD [ebp-8], 0xff ;MEGA_VAR
汇编语言的主要优点是其简单的语法和完整的信息方法(没有隐藏的东西,程序员控制一切)
虽然使用高级宏2没有错,但混合使用高级和低级方法会导致源文件更难为专家解析
此外,从本体论的角度来看,它没有什么意义:如果您想使用高级功能,那么像C这样的语言更适合,必须重新考虑汇编的使用。相反,如果你想学习如何进行低级编程,那么这样的宏是学习过程的障碍
最后,宏不是魔法。虽然灵活性很强,但程序员迟早会遇到限制。例如,我还没有深入研究FASM和NASM对对齐局部变量的支持
1此时,这不再是组装…
2个高级宏可以让您轻松地重构代码,这一点非常重要。不过,我们应该暂停一下,问问自己,当需要进行重要的重构时,如何选择使用汇编。FASM本机的方法是通过指令: 关于论点:
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
宏在内部使用virtual
。您可以为偏移量创建“eq”,但这不是非常健壮的解决方案,因为它们只有在基指针正确时才能工作,所以所有类型/ptr检查仍由程序员来完成。另外,如果在一个文件中有多个函数,则局部变量的名称可能会冲突。当我还年轻,不是很聪明的时候,我在ASM中做了一个大项目,我用r32+eq\u offset
来模拟OOP,这部分工作正常。如果将多个变量分组为“对象”,则创建函数来操作它们,如leaebx[ebp-30];对象“X”实例
调用Xsomething
。。。然后我终于学会了C++。“真正的汇编程序员使用注释”…当阅读别人的代码时,我有时会觉得“我很难编写代码,所以你应该很难阅读”——)@Tommyle2k加上那一刻,当你比作者更了解它时:/…;)。。。我同意评论的观点,当您将程序集用于与性能相关的事情时,它是完全有效的,只重写了较大项目的几个瓶颈。我可以想象拥有更复杂的语言结构对大型ASM项目有多大帮助,但根据我自己的经验(ASM文件总容量超过500kB),本地名称绝对不是大型ASM项目的最大问题:)。(即使我不是真正的程序员,我也同意,因为我不使用vi
或emacs
,只使用joe
)
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