【问题标题】:How to represent hex value such as FFFFFFBB in x86 assembly programming?x86汇编编程中如何表示FFFFFFBB等十六进制值?
【发布时间】:2012-07-28 20:13:56
【问题描述】:

我正在学习 x86 内联汇编编程。

我想写mov ecx, FFFFFFBB,但是编译器无法识别它。像这样的十六进制数字应该如何写在内联汇编代码中?

【问题讨论】:

标签: assembly x86 hex inline-assembly


【解决方案1】:

这取决于你的汇编器的风格。

  • 美国电话电报公司:movl $0xFFFFFFBB, %ecx
  • 英特尔:mov ecx, 0FFFFFFBBh

仅供参考,GNU Assembler 等汇编器使用 AT&T 语法,而 NASM 和大多数其他人使用英特尔的。

【讨论】:

  • 我使用 VC++ 10.0 、Digital Mars C++ 10.0 和 FASM 都使用英特尔风格。 0ffffffbbh
  • 事实上,GNU as、FASM 和 NASM 确实支持十六进制常量的 0xffffffbb 语法。 (GNU 需要 .intel_syntax noprefix 指令来使用 Intel 语法,或者将 -masm=intel 传递给 GCC)。
  • @Ruslan 我不知道 GCC 中的那个功能!谢谢!
【解决方案2】:

请参阅 标签 wiki 以获取汇编器手册和许多其他内容的链接。


不同的 x86 汇编器支持以下一种或两种十六进制常量语法:

  • 0xDEADBEEFNASM(和兼容),GNU asFASM,MSVC 内联汇编(但不是 MASM),emu8086。
  • 0DEADBEEFh:NASM(和兼容)、FASM、MASM、TASM、emu8086。

DOS/Windows-only 汇编器通常只支持...h 语法。
便携式汇编器通常支持0x... 语法,或两者​​兼有。

注意前导0: 数字常量总是必须以十进制数字开头,以将它们与符号名称区分开来。How do I write letter-initiated hexadecimal numbers in masm code? 专门针对这一点,用于尾随 h 样式。)

还请注意,汇编器,如 C 编译器,可以在汇编时评估表达式,因此您可以编写 foo & 0xF(如果 foo 是一个汇编器常量,用 foo equ 0xABC 或其他东西定义)。您甚至可以从标签中添加/减去标签(它们是链接时常量,而不是汇编时),所以像 mov eax, OFFSET label - 20 这样的东西仍然会汇编成 mov r32, imm32 mov-immediate 指令,只是使用不同的 32 位立即数。


来自NASM manual's section on constants

一些例子(都产生完全相同的代码):

    mov     ax,200          ; decimal 
    mov     ax,0200         ; still decimal 
    mov     ax,0200d        ; explicitly decimal 
    mov     ax,0d200        ; also decimal 
    mov     ax,0c8h         ; hex 
    mov     ax,$0c8         ; hex again: the 0 is required 
    mov     ax,0xc8         ; hex yet again 
    mov     ax,0hc8         ; still hex 
    mov     ax,310q         ; octal 
    mov     ax,310o         ; octal again 
    mov     ax,0o310        ; octal yet again 
    mov     ax,0q310        ; octal yet again 
    mov     ax,11001000b    ; binary 
    mov     ax,1100_1000b   ; same binary constant 
    mov     ax,1100_1000y   ; same binary constant once more 
    mov     ax,0b1100_1000  ; same binary constant yet again 
    mov     ax,0y1100_1000  ; same binary constant yet again

大多数汇编程序还允许 字符文字,例如 '0' 用于 ASCII 零。甚至 '0123' 将四个 ASCII 数字打包成一个 32 位整数。有些支持转义序列(\n'),有些(如 YASM)不支持。 NASM 仅支持反引号内的转义序列,不支持双引号。


其他平台:

ARM assembler: 0xDEADBEEF 有效。

我认为 0x... 是典型的。 0...h 主要是 DOS 的东西。

【讨论】:

  • MASM 汇编器本身不理解 0x 前缀,即使在现代版本的 Microsft 汇编器上也是如此。如果您在 VC/VC++ 中编译内联汇编代码,它应该在 __asm 语句中接受它。我不知道权威来源,但这是我多年来使用 MASM / Visual C/C++ 的经验。
  • 我确实确认了生成 16 位代码的最后一个 VC++ 版本(1993 年发布的 1.52c)支持 0x 作为内联汇编的前缀。我采用了最新的 VS 2015 的 MASM,它无法使用 0x 前缀组装程序集文件并使用 error A2206: missing operator in expression 中止
  • @MichaelPetch:感谢您的检查。更新了我的答案以不偏向于 DOS 风格的 0...h 所需语法,即使我个人不喜欢它。
【解决方案3】:

这取决于您的汇编程序,但十六进制文字的常用表示法是 0FFFFFFBBh

【讨论】:

    【解决方案4】:

    十六进制数字通常总是以0x 开头,因此您可以使用0xFFFFFFBB

    【讨论】:

    • 例如,这不适用于 masm、tasm 和 wasm。
    • 十六进制数字也可能类似于:FFFFFFBBh,尾随 h 而不是前导 0x
    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    相关资源
    最近更新 更多