应该怎样把值传给一段被编译后的机器码?

#include <stdio.h> /* 函数声明 */ int max(int num1, int num2); int main () { /* 局部变量定义 */ int a = 100; int b = 200; int ret; /* 调用函数来获取最大值 */ ret = max(a, b); printf( "Max value is : %d\n", ret ); return 0; } /* 函数返回两个数中较大的那个数 */ int max(int num1, int num2) { /* 局部变量声明 */ int result; if (num1 > num2) result = num1; else result = nu…
关注者
44
被浏览
6134
请问题主的意思是类似这样的场景么?
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>

typedef int (*binary_func_t)(int, int);

int main() {
  char code[] = { 0x48, 0x89, 0xF8, 0x48, 0x39, 0xF7, 0x48, 0x0F, 0x4C, 0xC6, 0xC3 };
  char* code_buf = mmap(NULL, sizeof(code), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
  memcpy(code_buf, code, sizeof(code));
  mprotect(code_buf, sizeof(code), PROT_READ|PROT_EXEC);

  binary_func_t max = (binary_func_t)code_buf;
  int n = max(3, 42);
  printf("max(3, 42) = %d\n", n);

  munmap(code_buf, sizeof(code));

  return 0;
}

// Use MAP_ANON instead of MAP_ANONYMOUS on Mac OS X
这是我在Mac OS X / x86-64上写的个小测试。对应Windows上的话 mmap -> VirtualAlloc,mprotect -> VirtualProtect。

如果是这样的场景的话,题主想问的是在我的例子中 max(3, 42) 那里参数是如何传递过去的么?其实没啥特别的,就是按照给定的calling convention来啊。
我的例子里就是用默认的System V ABI的calling convention,两个参数分别从RDI、RSI传递,返回值从RAX传递。

题主在Windows上实验的话,那么就参考您的编程环境里的默认calling convention来搞就好了。
如果题主没留意过的话,其实函数指针类型上是可以声明calling convention修饰符的,不写就是用默认的calling convention。例如说:
typedef int (__stdcall *binary_func_t)(int, int);
typedef int (__cdecl *binary_func_t)(int, int);
typedef int (__fastcall *binary_func_t)(int, int);
等等。这样就可以根据目标函数的实现状况来在caller一侧选择合适的calling convention与之匹配了。