如何强制 NASM 将 int3 编码为 0xCC

Tre*_*rey 1 x86 assembly nasm machine-code

我正在尝试使用 NASM 组装以下代码

 section .text
 global _start


_start:

mov eax, 1
int 3
Run Code Online (Sandbox Code Playgroud)

objdump -D产量:

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
Run Code Online (Sandbox Code Playgroud)

有趣的是,当用 GAS 组装时,int 3被编码为0xCC而不是cd 03,这是为什么呢?

Pet*_*des 5

使用int3特殊一字节编码的助记符。

\n
nasm -l /dev/stdout /tmp/foo.asm\n 1 00000000 CD03                    int 3\n 2 00000002 CC                      int3\n
Run Code Online (Sandbox Code Playgroud)\n
\n

从英特尔的 insn 设置手动输入int:

\n
\n

INTO由或INT3(CC)生成的中断与由 生成的中断INT n在以下方面有所不同:

\n
    \n
  • 在 virtual-8086 模式下不会发生正常的 IOPL 检查。任何 IOPL 值都会产生中断(无故障)。

    \n
  • \n
  • 不会发生由虚拟 8086 模式扩展 (VME) 启用的中断重定向。中断始终由保护模式处理程序处理。

    \n
  • \n
\n

这些功能不属于 CD03,即 INT 3 的 \xe2\x80\x9cnormal\xe2\x80\x9d 2 字节操作码

\n
\n

它还说:

\n
\n

Intel 和 Microsoft 汇编器不会从任何助记符生成 CD03 操作码

\n
\n

因为 2 字节编码没有任何正常/常见的用例。NASM 保持简单并始终使用CD操作码作为int助记符。

\n

当 NASM 确实优化诸如mov rax, 1to之类的东西时mov eax,1,它是使用相同助记符的不同操作码。我不知道实施起来是否不方便,或者 NASM 干脆决定不这样做。将其视为int3一条特殊指令是有意义的,但与 不同int n,因为它只有 1 个字节。

\n

  • 遗憾的是他们没有使用不同的助记符(例如“break”),以便区分软件中断(受权限检查,如果这些检查失败可能会生成一般保护错误)和断点异常之间的区别(这不是软件中断并且不受特权检查)更明显。 (2认同)