【问题标题】:NASM Assembly - what is the ", 0" after this variable for?NASM 程序集 - 这个变量后面的“,0”是什么?
【发布时间】:2018-12-07 10:49:48
【问题描述】:

就在我按照指南在汇编中使用 MessageBoxA 函数之前,在创建变量时,他们在变量内容后使用了“,0”。这是干什么用的?

代码如下所示:

paramText  db  "this is text", 0

【问题讨论】:

  • C 字符串以空字符结尾(并且 messageboxa 需要以空字符结尾的字符串)

标签: windows variables assembly nasm


【解决方案1】:

db 是“定义字节”,此代码将生成这些字节(十六进制格式):

74 68 69 73 20 69 73 20 74 65 78 74 00

引号中的“字符串”被拆分为单个字符的ASCII字符代码(我相信NASM中的UTF8也是可能的,所以一个字符可能会产生多个字节),最后一个值“,0”被编译为那个,为零。

db 1, 2, 3 会产生 3 个机器码字节 01 02 03

最后一个字母后面的零作为“字符串 nul 终止符”供其他代码使用,它接受以零结尾的字符串(如 MessageBoxA 代码)。

“变量”是编程中比较高级的概念,机器不直接支持,编译时得到的是“符号/符号名”paramText,等于first的内存地址在它之后定义的字节(0x74)= 这可以在编译时用于处理该地址。然后db 产生实际的二进制机器代码 = 它将在运行时存在,作为操作系统加载到内存中的值。如果您想这样考虑的话,最后一个零是此上下文中“可变内容”的一部分(而不是“之后”)。

但它只是计算机内存中的二进制值。 “变量”逻辑(包括类型和/或格式)是由代码创建的,它使用内存进行操作,并且由编程语言+编译器创建,允许在源代码中进行这样的构造,但 CPU 本身并不知道这个概念,并且它只对位进行操作(通常分组为字节、字等)。


编辑:您实际上也可以在 NASM 中使用类似 C 的字符串转义值,但字符串必须用反引号括起来,例如:

paramText:  db  `this is text\0`

引号和撇号不会扫描字符串文字以查找转义序列,并将“\0”编译为两个字符。但是使用“, 0”作为下一个字节定义更容易记住 IMO,而不是记住反引号/引号定义的字符串之间的区别,这是 NASM 特定的功能,并非所有 x86 汇编程序都支持。

【讨论】:

  • @smokals 你也可以在使用 NASM 编译时使用-l <listing_file_name> 选项来获得与生成的机器代码混合的源代码,这可能有助于更好地理解汇编程序在开始时生成的内容,我在为代码大小编程时经常使用它,所以我可以看到源代码的哪些部分产生了大量的机器代码字节,并检查我是否可以用一些更小的机器代码序列重写这些部分(即使它需要更多的指令在源代码中)。
【解决方案2】:

MessageBoxA 函数需要一个 null 终止 字节字符串。零只是 null-terminator,它告诉所有接受字符串的 C 函数,字符串在哪里结束。

【讨论】:

    【解决方案3】:

    它实际上是字节零,很可能是为了创建null-terminated string

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-25
      • 2011-02-12
      • 1970-01-01
      • 2020-05-22
      相关资源
      最近更新 更多