ElBlo
Harry Potter and the Cursed Assembler
GNU AS, the assembler, has a very strange behavior when it comes to specifying operation sizes while using the Intel syntax.
.global _start
.intel_syntax noprefix
_start:
mov al, BYTE [rdi]
mov ax, WORD [rdi]
mov al, BYTE PTR [rdi]
mov ax, WORD PTR [rdi]
gas
, assembles1 it into:
_start:
mov al,BYTE PTR [rdi+0x1]
mov ax,WORD PTR [rdi+0x2]
mov al,BYTE PTR [rdi]
mov ax,WORD PTR [rdi]
Why is that? Well, because gas
has special values for BYTE
, WORD
,
DWORD
, and QWORD
that get replaced to 1
, 2
, 4
, and 8
, respectively.
This means that mov al, BYTE [rdi]
gets interpreted as mov al, 1[rdi]
which
to gas
, is the same as mov al, [rdi + 1]
.
If you are familiar with nasm
, you would probably use the first instructions,
and get bit by the issue. Luckily, LLVM’s assembler rejects this input:
<source>:4:19: error: Expected 'PTR' or 'ptr' token!
mov al, BYTE [rdi]
^