asmjit 备忘表

// mov rcx,0
a.mov(rcx, 0);

a.mov(rax, ptr(rcx) );    // mov rax, [rcx]
a.mov(rax, ptr(rbp, 16)); // mov rax [rbp+0x10]

// 字符串
a.mov(rdx, "body");

查看字节码

  CodeBuffer& buffer = code.textSection()->buffer();
  printf("size: %d\n", buffer.size());
  for (size_t i = 0; i < buffer.size(); i++)
    printf("%02X ", buffer[i]);

当前程序的运行环境

Environment env = hostEnvironment();
printf("%d\n", env.is64Bit());
printf("%d\n", env.is32Bit());

使用虚拟内存分配器JitAllocator而不是JitRuntime

https://asmjit.com/doc/group__asmjit__core.html#autotoc_md17

  Environment env = hostEnvironment();
  uint8_t* p = (uint8_t*)VirtualAlloc(0, 1024, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

  CodeHolder code;
  code.init(env, (uint64_t)p);
  x86::Assembler a(&code);

  if (env.is64Bit())
    a.mov(rax, 64);
  else
    a.mov(eax, 32);
  a.ret();

  code.relocateToBase((uint64_t)p);
  size_t codeSize = code.codeSize();
  code.copyFlattenedData(p, codeSize, CodeHolder::kCopyPadSectionBuffer);

  printf("%p\n", p);
  printf("%d\n", ptr_as_func<Func>(p)());

  VirtualFree(p, 0, MEM_RELEASE);

定义label

  typedef int (*Func)(BOOL isPlayer);

  JitRuntime rt;

  CodeHolder code;
  code.init(rt.environment());
  x86::Assembler a(&code);

  Label player = a.newLabel();
  Label enemy = a.newLabel();
  Label _return = a.newLabel();

  a.test(rcx, rcx);
  a.jz(enemy);

  a.bind(player);
  a.mov(rax, 999);
  a.jmp(_return);

  a.bind(enemy);
  a.mov(rax, 0);

  a.bind(_return);
  a.ret();


  Func fn;
  rt.add(&fn, &code);

  printf("%d\n", fn(1)); // 999
  printf("%d\n", fn(0)); // 0

  rt.release(fn);

指定数据大小

  JitRuntime rt;

  CodeHolder code;
  code.init(rt.environment());
  x86::Assembler a(&code);
  Label data = a.newLabel();

  // 用32位寄存器会编译为 mov eax,dword ptr [data-4]
  // 用64位寄存器会编译为 mov rax,qword ptr [data-4]
  a.mov(eax, ptr(data, -4)); 
  a.mov(edx, ptr(data));
  a.add(eax, edx);
  a.ret();

  a.align(AlignMode::kAlignZero, 8);
  a.dd(1);
  a.bind(data);
  a.dd(2);

  Func fn;
  rt.add(&fn, &code);
  printf("%p\n", fn()); // 3

  rt.release(fn);

float

  a.movss(xmm0, ptr(data));
  a.ret();

  a.align(AlignMode::kAlignZero, 8);
  a.bind(data);
  a.embedFloat(1.23);

double

  a.movsd(xmm0, ptr(data));
  a.ret();

  a.align(AlignMode::kAlignZero, 8);
  a.bind(data);
  a.embedDouble(1.23);

code offset

  • offset 返回CodeBuffer中的当前位置
  • setOffset 将CodeBuffer中的当前位置设置为offset
  Assembler a(&code);

  a.mov(eax, 1);
  printf("%d\n", a.offset()); // 5 
  a.ret();
B8 01 00 00 00       mov         eax,1  
C3                   ret 

bufferData

返回当前部分中CodeBuffer的开始

  Assembler a(&code);

  a.mov(eax, 1);
  a.ret();

  printf("%p\n", a.bufferData());
  printf("%p\n", a.bufferEnd());
  printf("%p\n", a.bufferPtr());

CodeHolder

  CodeHolder code;
  code.init(rt.environment());
  Assembler a(&code);

  a.mov(eax, 1);
  a.ret();

  printf("%d\n", code.codeSize()); // 所有节字节大小,现在只有.text一个节, 6
  printf("%p\n", code.sectionCount()); // 节数,1
  for  (auto s : code.sections())
  {
    printf("name: %s\n", s->name()); // .text
    printf("data: %p\n", s->data()); // 节基址
    printf("buf size: %d\n", s->bufferSize()); // 节字节大小6
    printf("size: %d\n", s->buffer().size()); // 节字节大小6
    printf("func: %p\n", s->buffer().data()); // 返回指向缓冲区引用的数据的指针
  }

  // code.textSection(); // 指定获取.text节

自定义环境体系

  Environment env = hostEnvironment();
  env.setArch(Environment::kArchX86); // 默认会使用当前程序的环境,但是你可以主动设置

  CodeHolder code;
  code.init(env);

  printf("is64Bit: %d\n", env.is64Bit()); // 0
posted @ 2021-04-15 09:36  Ajanuw  阅读(85)  评论(0编辑  收藏  举报