1

I'm trying to assemble the following code with NASM

 section .text
 global _start


_start:

mov eax, 1
int 3

Objdump -D yields:

test:     file format elf64-x86-64


Disassembly of section .text:

0000000000400080 <_start>:
 400080:    b8 01 00 00 00          mov    $0x1,%eax
 400085:    cd 03                   int    $0x3

Interestingly enough, when assembled with GAS, int 3 is encoded as 0xCC rather than cd 03, why is that?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Trey
  • 474
  • 2
  • 9
  • 32
  • 1
    note that [one of the reasons MS chose to fill uninitialized memory with 0xCC to aid debugging is because of the `int 3`](https://stackoverflow.com/a/370274/995714) – phuclv Mar 12 '18 at 08:09

1 Answers1

5

Use the int3 mnemonic for the special one-byte encoding.

nasm -l /dev/stdout /tmp/foo.asm
 1 00000000 CD03                    int 3
 2 00000002 CC                      int3

From the Intel's insn set manual entry for int:

An interrupt generated by INTO or INT3 (CC) differs from one generated by INT n in the following ways:

  • The normal IOPL checks do not occur in virtual-8086 mode. The interrupt is taken (without fault) with any IOPL value.

  • The interrupt redirection enabled by the virtual-8086 mode extensions (VME) does not occur. The interrupt is always handled by a protected-mode handler.

These features do not pertain to CD03, the “normal” 2-byte opcode for INT 3

It also says:

Intel and Microsoft assemblers will not generate the CD03 opcode from any mnemonic

because there aren't any normal / common use-cases for the 2-byte encoding. NASM keeps it simple and always uses the CD opcode for the int mnemonic.

When NASM does optimize things like mov rax, 1 to mov eax,1, it's a different opcode that uses the same mnemonic. IDK if it would have been inconvenient to implement, or if NASM simply decided not to. It makes sense to think of int3 as a special instruction, different from int n, though, because it's only 1 byte.

Community
  • 1
  • 1
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Aside from backward compatibility, what's the point of using **CD03** ? – Trey Mar 12 '18 at 07:27
  • 1
    @Trey: they behave differently in vm86 mode. Other than that, probably no reason to ever type `int 3` instead of `int3`, but NASM gives you the option. – Peter Cordes Mar 12 '18 at 07:42
  • 2
    It's a pity they didn't use a different mnemonic (e.g. "`break`") so that the difference between a software interrupt (which is subject to privilege checks and may generate a general protection fault if those checks fail) and a breakpoint exception (which is not a software interrupt and not subject to privilege checks) is more obvious. – Brendan Mar 12 '18 at 08:19
  • 1
    @Brendan: "They" being Intel in this case, right? Yeah, agreed. – Peter Cordes Mar 12 '18 at 08:21
  • 1
    @Brendan - Lack of foresight, perhaps? The instruction set was designed first, in the 70's. Privilege levels and protection were piggy-backed later, in the 80's. Not many expected this to live long into the next millennium. :-) – Bo Persson Mar 13 '18 at 00:02