概述
首先生成机器码
为下面函数生成机器码:
// mul.c
int mul(int a, int b) {
return a*b;
}
然后编译汇编之,生成 object
文件:
gcc -c mul.c -o mul.o
从 mul.o 中提取机器码:
objdump -j .text -d mul.o
mul.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <mul>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 8b 45 fc mov -0x4(%rbp),%eax
d: 0f af 45 f8 imul -0x8(%rbp),%eax
11: 5d pop %rbp
12: c3 retq
每行冒号后面的十六进制数字就是机器码了,机器码后面有汇编提示(很贴心)。
执行机器码
从上面输出中抠出机器码,写入下面c
程序中:
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
int main() {
// 这里的机器码就是从objdump的输出中抠出的
static char code[] = {
0x55,
0x48, 0x89, 0xe5,
0x89, 0x7d, 0xfc,
0x89, 0x75, 0xf8,
0x8b, 0x45, 0xfc,
0x0f, 0xaf, 0x45, 0xf8,
0x5d,
0xc3
};
// 分配一段内存(可写可执行),用来存储机器代码
void *mem = mmap(NULL, sizeof(code), PROT_WRITE | PROT_EXEC,MAP_ANON | MAP_PRIVATE, -1, 0);
// 将机器码存入内存中
memcpy(mem, code, sizeof(code));
// 类型转换,将内存转换成函数指针
int (*fn)() = mem;
// 调用函数指针
printf("14 * 2rresult: %d/n", fn(14, 2));
// 释放分配的内存
munmap(mem, sizeof(code));
}
有啥用呢?
上面的c
程序展示了在运行时(runtime)执行生成机器并执行之。这个能力想想是不是有种似曾相识的感觉?对,就是jit
,just in time
compilation。
jit
广泛用于python、lua 等静态语言等解释执行上。
最后
以上就是朴素白开水为你收集整理的执行机器码的全部内容,希望文章能够帮你解决执行机器码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复