Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 在堆栈中创建命名变量_Assembly_Nasm_Fasm - Fatal编程技术网

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