程序集 x86 - 变量赋值

Assembly x86 - variable assignment

假设我有一个名为 Block_Size 的变量并且没有初始化。

Block_Size db ?

mov DS:Block_Size, 1

等于

Block_Size db 1

db 的字面意思是 "define byte",所以它会将字节放在那里,移动命令可以让您将特定值放在寄存器中,覆盖那里的任何其他内容。

不,Block_Size db ? 必须进入 BSS 或数据部分,而不是与您的代码混合。

如果你写了

my_function:
    Block_Size db ?
    mov DS:Block_Size, 1
    ...
    ret

你的代码会崩溃。 ? 并不是真正的未初始化,它实际上是归零的。因此 CPU 解码了从 my_function 开始的指令(例如在其他一些代码 运行 call my_function 之后),它实际上会将 0 解码为代码。 (IIRC,操作码 0 是 add,然后 mov 指令的操作码将被解码为 add (ModR/M) 的 ope运行d 字节.)

尝试组装它,然后使用反汇编器向您展示它是如何解码的,以及机器代码的十六进制转储。

db在当前位置将一个字节组装到输出文件中,就像add eax, 283 c0 02组装到输出文件中一样。

您不能像在 C

中声明变量那样使用 db
void foo() {
   unsigned char Block_size = 1;
}

非优化编译器会在堆栈上为 Block_size 保留 space。如果您好奇,请查看编译器 asm 输出。 (但如果启用优化,它会更具可读性。您可以使用 volatile 强制编译器实际存储到内存中,以便您可以在优化代码中看到那部分 asm。)

可能相关:Assembly - .data, .code, and registers...?


如果你写了

.data
        Block_size    db ?

.code
set_blocksize:
        mov    [Block_size], 1
        ret

有点像这样 C:

unsigned char Block_size;
void set_blocksize(void) {
    Block_size = 1;
}

如果您不需要将某些内容保存在内存中,请不要使用 dbdd。将其保存在寄存器中。或者使用 Block_size equ 1 来定义一个常量,这样你就可以做类似 mov eax, Block_size + 4 的事情而不是 mov eax, 5.

变量是一个高级概念,汇编并不真正拥有。在 asm 中,您正在使用的数据可以在某个寄存器或内存中。为它预留静态存储通常是不必要的,尤其是对于小程序。使用注释来跟踪您在哪个寄存器中输入的内容。