了解如何手动发出处理器指令

时间:2013-10-16 02:39:06

标签: c++ linux assembly

我正在阅读一篇关于如何构建 Jit Compiler的文章,作者基本上使用了这段代码:

// Processor instructions for:
//   mov eax, 0   
//   ret 
unsigned char code[] = {0xb8, 0x00, 0x00, 0x00, 0x00, 0xc3};

void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC,
    MAP_ANON | MAP_PRIVATE, -1, 0);  

memcpy(mem, code, sizeof(code));

int (*func)() = mem;   
return func();

我得到了关于代码的所有内容,除了他如何知道如何手动将汇编程序指令映射到数字代码。为了理解这一点,我需要学习什么?

3 个答案:

答案 0 :(得分:4)

有引用(such as these for Intel 64 and IA-32),它们涵盖了汇编指令映射到实际机器代码的方式。这当然会在CPU /环境之间 - 例如以上内容不适用于ARM系统。

或者,可以从现有生成的输出中复制值,例如从汇编程序的输出中复制。

答案 1 :(得分:3)

我是文章作者,希望你喜欢它!

为了构建这些值,我基本上做了

$ cat test.S
  .intel_syntax noprefix
  mov eax, 0
  ret
$ gcc -c -o test.o test.S
$ objdump -d -M intel test.o

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:   b8 00 00 00 00          mov    eax,0x0
   5:   c3                      ret

您可以在左栏中看到说明的字节。除非你有充分的理由,否则我不建议深入研究指令编码。它们非常复杂,装配工非常善于生成这些东西。在这个级别还有很多其他的东西要学习,以便更好地利用你的大脑能量。阅读Agner Fog's manuals以获得良好的开端。

答案 2 :(得分:1)

您可以使用许多库来编写JIT。 AsmJit将帮助您发出机器代码指令(在x86上)。 GNU lightninglibjitLLVM会将一些抽象指令集(或抽象语法树)转换为机器代码。

处理器Instruction Set Architecture被记录在案(长期无聊的文件中)。对于x86,您可能需要阅读数千页。