I have this:
bits 16
global start
section .text
start:
add cx, 1234
With this Makefile:
test:
@nasm -f macho64 test.asm
@objdump -x86-asm-syntax=intel --full-leading-addr -d test.o
.PHONY: test
It prints:
% make
test.o: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000000000000 start:
0: 81 c1 <unknown>
2: d2 04 <unknown>
Why does it produce the <unknown>
and not show the instruction here? Did I do something wrong? Still learning the very basics of machine code so sorry if it's obvious.
It seems to work fine in 32 bit mode:
bits 32
global start
section .text
start:
add cx, 1234
Outputs:
% make
test.o: file format Mach-O 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000000000000 start:
0: 66 81 c1 d2 04 add cx, 1234
opcode 81
in 64-bit mode requires 5 more bytes (modrm + imm32), but your .text
segment ends before that so the disassembler gives up. If you pad the text section with some more bytes (like times 10 db 0
), you'll get something.
You used bits 16
to put non-64-bit machine code into a 64-bit object file, so of course you should expect things to be wrong in general.
16-bit mode has a different default operand-size (16) than 32 and 64-bit mode (32), so the 66
operand-size prefix makes things opposite. Instructions that require a 66
prefix in 32 or 64-bit mode (like add cx, 1234
), require it to be absent in 16-bit mode. (As mentioned in @fuz's answer to your previous question)