x86汇编编程中如何表示FFFFFFBB等十六进制值?

Posted

技术标签:

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

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

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

【问题讨论】:

什么编译器/汇编器? MASM 的另一个版本:How do I write letter-initiated hexadecimal numbers in masm code? 【参考方案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】:

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


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

0xDEADBEEF:NASM(和兼容),GNU as,FASM,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

以上是关于x86汇编编程中如何表示FFFFFFBB等十六进制值?的主要内容,如果未能解决你的问题,请参考以下文章

零基础学汇编语言x86

二进制分析实战:x86汇编快速入门

X86汇编4.基本指令详解

如何在 x86 汇编语言中创建嵌套循环

如何在 x86 汇编中编写自己的 atoi 函数

《80X86汇编语言程序设计教程》十一 32位代码段和16位代码段切换实例