.byte 汇编指令在 gnu 汇编中有何用途?
在查看一些具有内联汇编的 C 代码时,我遇到了 .byte(开头有一个点)指令。
在检查网络上的程序集参考时,我发现它用于在内存中保留一个字节。
但在代码中,语句之前没有标签。所以我想知道未标记的 .byte 指令或任何其他数据存储指令有什么用。
例如,如果我编码 .byte 0x0a
,我该如何使用它?
While going through some C code having inline assembly I came across the .byte (with a Dot at the beginning) directive.
On checking the assembly reference on web I found that it is used to reserve a byte in memory.
But in the code there was no label before the statement. So I was wondering what is use of an unlabeled .byte directive or any other data storage directive for that matter.
For e.g. if i code .byte 0x0a
, how can i use it ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有几种可能性......这里有一些我能立即想到的:
您可以相对于
.byte之后的标签来访问它
指令。示例:<前><代码> .byte 0x0a
标签:
mov(标签 - 1),%eax
根据程序的最终链接布局,
.byte
指令可能会作为代码执行。通常,在这种情况下您也会有一个标签,但是...某些汇编器不支持为操作数大小等生成 x86 指令前缀。在为这些汇编器编写的代码中,您经常会看到类似以下内容的内容:
<前><代码> .byte 0x66
移动 $12,%eax
为了让汇编器发出您想要的代码。
There are a few possibilities... here are a couple I can think of off the top of my head:
You could access it relative to a label that comes after the
.byte
directive. Example:Based on the final linked layout of the program, maybe the
.byte
directives will get executed as code. Normally you'd have a label in this case too, though...Some assemblers don't support generating x86 instruction prefixes for operand size, etc. In code written for those assemblers, you'll often see something like:
To make the assembler emit the code you want to have.
最小可运行示例
.byte
无论您身在何处,都会吐出字节。是否有标签指向字节并不重要。如果您碰巧位于文本段中,那么该字节可能会像代码一样运行。
Carl 提到了这一点,但这里有一个完整的示例,可以让它进一步深入:Linux x86_64 的
true
实现,其中抛出了nop
:生成与以下完全相同的可执行文件:
因为
nop
被编码为字节0x90
。一种用例:新指令
一种用例是向 CPU ISA 添加新指令,但只有非常边缘版本的汇编器才支持它。
因此,项目维护者可能会选择直接内联字节,以使其可以在较旧的汇编器上编译。
例如,请参阅 Linux 内核上的 Spectre 解决方法,使用类似的
.inst
指令:https://github.com/torvalds/linux/blob/94710cac0ef4ee177a63b5227664b38c95bbf703/arch/arm/include/asm/barrier.h#L23为Spectre添加了一条新指令,内核决定暂时对其进行硬编码。
Minimal runnable example
.byte
spits out bytes wherever you are. Whether there is a label or not pointing to the byte, does not matter.If you happen to be in the text segment, then that byte might get run like code.
Carl mentioned it, but here is a complete example to let it sink in further: a Linux x86_64 implementation of
true
with anop
thrown in:produces the exact same executable as:
since
nop
is encoded as the byte0x90
.One use case: new instructions
One use case is when new instructions are added to a CPU ISA, but only very edge versions of the assembler would support it.
So project maintainers may choose to inline the bytes directly to make it compilable on older assemblers.
See for example this Spectre workaround on the Linux kernel with the analogous
.inst
directive: https://github.com/torvalds/linux/blob/94710cac0ef4ee177a63b5227664b38c95bbf703/arch/arm/include/asm/barrier.h#L23A new instruction was added for Spectre, and the kernel decided to hardcode it for the time being.
下面是一个内联汇编的示例:(
参见 编译器 asm 输出以及 Godbolt 编译器资源管理器上最终二进制文件的反汇编。)
您可以将
.byte 0xb8, 0x01, 0x00, 0x00, 0x00
替换为移动 $1,%%eax
运行结果将是相同的。这表明它可以是一个字节,可以表示一些指令,例如移动或其他指令。
Here's an example with inline assembly:
(See compiler asm output and also disassembly of the final binary on the Godbolt compiler explorer.)
You can replace
.byte 0xb8, 0x01, 0x00, 0x00, 0x00
withmov $1, %%eax
the run result will be the same. This indicated that it can be a byte which can represent some instruction eg- move or others.
.byte 是一个指令,允许您声明一个仅通过检查可知的常量字节,无需任何上下文。
来自 GNU 汇编器指南:
The .byte is a directive that allows you to declare a constant byte only known through inspection without any context.
From the GNU Assembler Guide: