汇编中的变量到底是什么?

Bru*_*iro 3 windows assembly nasm windows-10

我是 x86 汇编的新手,最近使用 nasm 做了一些实验并在 Windows 10 计算机上运行该程序。

我有这个代码:

global _start
extern  _GetStdHandle@4
extern  _WriteFile@20
extern  _ExitProcess@4
section .data
    message db "1234"
section .text
_start:
    call print
    call _ExitProcess@4
print:
    ; DWORD  bytes;    
    mov     ebp, esp
    sub     esp, 4

    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
    push    -11
    call    _GetStdHandle@4
    mov     ebx, eax

    ; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push    0
    lea     eax, [ebp-4]
    push    eax
    push    4
    push    message
    push    ebx
    call    _WriteFile@20
    mov     esp, ebp
    ret

    ; ExitProcess(0)
Run Code Online (Sandbox Code Playgroud)

我使用以下命令组装它:

nasm -f win32 out.asm
link out.obj /entry:start /subsystem:console "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x86\kernel32.lib"
Run Code Online (Sandbox Code Playgroud)

当在 cmd 上运行它时,它按预期输出“1234”

现在,当汇编并运行以下代码时,程序不直接推送消息,而是直接推送“1234”

global _start
extern  _GetStdHandle@4
extern  _WriteFile@20
extern  _ExitProcess@4
section .data
    message db "1234"
section .text
_start:
    call print
    call _ExitProcess@4
print:
    ; DWORD  bytes;    
    mov     ebp, esp
    sub     esp, 4

    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
    push    -11
    call    _GetStdHandle@4
    mov     ebx, eax

    ; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push    0
    lea     eax, [ebp-4]
    push    eax
    push    4
    push    "1234"
    push    ebx
    call    _WriteFile@20
    mov     esp, ebp
    ret
Run Code Online (Sandbox Code Playgroud)

它什么也不输出

为什么?消息中有哪些信息是“1234”没有的?当推送消息时,程序是否只推送存储“1234”的内存地址?如果是这样,我可以将“1234”存储在其他地方,然后在不创建变量的情况下推送其地址吗?

Eri*_*idt 5

变量是一个逻辑结构 \xe2\x80\x94 变量有生命周期,有的短,有的长。\xc2\xa0 它们可以产生和消失。

\n

相比之下,寄存器和内存在某种意义上是物理结构 \xe2\x80\x94,它们始终存在。

\n

在汇编编程中,由人类或编译器生成,我们将 C 代码、算法和伪代码所需的逻辑变量映射到处理器中可用的物理存储。\xc2\xa0 当变量的生命周期结束时,我们可以重用用于其他目的(另一个变量)的物理存储。

\n

汇编语言支持全局变量(完整进程生命周期)和局部变量 \xe2\x80\x94 ,它们可以位于堆栈上的内存中,也可以位于 CPU 寄存器中。\xc2\xa0 CPU 寄存器当然没有地址,因此无法通过(内存)引用传递。\xc2\xa0 CPU 寄存器也无法索引,因此索引数组需要内存。

\n

  • 操作系统和CPU共同虚拟化内存,因此每个进程似乎都有自己的地址空间,并且具有相似的地址。CPU 知道(由操作系统编程)在执行指令的任何时刻它正在工作哪个地址空间。堆栈和全局内存只是地址空间的一部分,因此它们具有不同的内存地址。正如我所提到的,在某些条件下,局部变量必须位于 RAM 中(您希望通过引用传递它们,或索引它们),否则它们是 CPU 寄存器的潜在候选者。全局变量也需要 RAM。 (2认同)