【问题标题】:Assembly x86 - variable assignment汇编 x86 - 变量赋值
【发布时间】:2017-10-06 19:56:41
【问题描述】:

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

Block_Size db ?

mov DS:Block_Size, 1

等于

Block_Size db 1

【问题讨论】:

  • 如果您对如此基本的问题有疑问,这表明您需要一份好的 x86 汇编参考指南。
  • db 表示空间中的 1 个字节,mov ..., 1 表示将值设置为 1
  • Block_Size = 1 是什么意思?最直接的含义(在运行时更改标签的数值)是荒谬的,通常这不是预期的含义,但在这个问题的上下文中,它看起来可能就是你的意思。
  • 致哈罗德:好的,让我这样解释我的问题:“Block_Size db?”和 "mov DS:Block_Size, 1" 一起等于 "Block_Size db 1" ?
  • 好的,这更清楚了,但是“相等”的确切含义是什么。即使两种做某事的方法(通常)具有相似的结果,但如果它们是完全不同的方法,它们真的可以被称为平等吗?

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


【解决方案1】:

不,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 中,您正在使用的数据可以在寄存器或内存中的某个地方。为其保留静态存储通常是不必要的,尤其是对于小型程序。使用 cmets 跟踪您在哪个寄存器中放入的内容。

【讨论】:

    【解决方案2】:

    db 字面意思是“定义字节”,因此它将把字节放在那里,移动命令可以让你在寄存器中放置一个特定值,覆盖那里的任何其他值。

    【讨论】:

    • 感谢您的回复。这些代码是否等于“Block_Size db 1”? DS:Block_Size 让我很困惑。可以理解为(DS+Block_Size)处的地址,其内容为1。我说的对吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多