本文将介绍GAS.byte的用法。

权威说法

.byte expects zero or more expressions, separated by commas. Each expression is assembled into the next byte.

本文主要内容转载自:What is the use of .byte assembler directive in gnu assembly?

Minimal runnable example

.byte spits out bytes wherever you are.

If you happen to be in the text segment, then that byte might get run like code.

Here’s a Linux x86_64 implementation of exit(0) with a nop thrown in:

1
2
3
4
5
6
.global _start
_start:
mov $60, %rax
nop
mov $0, %rdi
syscall

produces the exact same executable as:

1
2
3
4
5
6
.global _start
_start:
mov $60, %rax
.byte 0x90
mov $0, %rdi
syscall

since nop is encoded as the byte 0x90.

Here’s the method to run the example:

1
as -o my_exit.o my_exit.s && ld -s -o my_exit my_exit.o && ./my_exit

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#L23

1
#define CSDB    ".inst  0xe320f014"

A new instruction was added for Spectre, and the kernel decided to hardcode it for the time being.