程序集x86 - 变量赋值

时间:2017-10-06 19:56:41

标签: variables assembly x86 variable-assignment memory-address

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

Block_Size db ?

mov DS:Block_Size, 1

等于

Block_Size db 1

2 个答案:

答案 0 :(得分:3)

不,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)的操作数字节。)

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

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

您不能像在C

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

非优化编译器会在堆栈上为Block_size保留空间。如果你很好奇,请查看编译器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中,您正在使用的数据可以位于寄存器或内存中。为它保留静态存储通常是不必要的,特别是对于小程序。使用注释来跟踪您在哪个寄存器中放置的内容。

答案 1 :(得分:1)

db字面意思是"定义字节"所以它会将字节放在那里,其中move命令可以让你在寄存器中放置一个特定的值来覆盖其他任何东西。