[英]Writing ARM machine instructions and executing them from C (On the Raspberry pi)
我正在尝试用C和ARM编写一些自修改代码。 我之前曾问过一个关于MIPS的类似问题 ,现在我正试图将该项目移植到ARM。
我的系统:=覆盆子pi上的Raspbian,ARMv6,GCC
有一些我不确定的事情:
我也试了一个例子
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
int inc(int x){ //increments x
uint16_t *ret = malloc(2 * sizeof(uint16_t));
*(ret + 0) = 0x3001; //add r0 1 := r0 += 1
*(ret + 1) = 0x4770; //bx lr := jump back to inc()
int(*f)(int) = (int (*)(int)) ret;
return (*f)(x);
}
int main(){
printf("%d",inc(6)); //expect '7' to be printed
exit(0);}
但我不断收到分段错误。 我正在使用aapcs调用约定,我已经了解它是所有ARM的默认值
如果有人指出我正确的方向,我会非常感激
奖金问题(意思是,它实际上不需要回答,但很难知道) - 我“来自MIPS背景”,ARM程序员如何在没有0寄存器的情况下做到这一点? (如,一个硬编码为0的寄存器)
在blogs.arm.com
上阅读缓存和自我修改代码 。 文章也包含了一个例子,它描述了你所描述的内容。
从文章中回答你的问题
... ARM架构通常被认为是改进的哈佛架构。 ...
纯哈佛架构的典型缺点是指令存储器不能从与数据存储器相同的地址空间直接访问,尽管此限制不适用于ARM。 在ARM上,您可以将指令写入内存,但由于D-cache和I-cache不一致,新写入的指令可能被I-cache的现有内容屏蔽,导致处理器执行旧指令(或可能无效)说明。
有关如何使缓存无效,请参阅__clear_cache 。
如果您打算将指令推送到内存中,我希望您也了解ARM / Thumb指令集。
有几个问题。
好的,所以这适用于我的覆盆子Pi。
#include <stdio.h>
#include <sys/mman.h>
#include <stdint.h>
#include <stdlib.h>
int inc(int x){ //increments x
uint32_t *ret = mmap(NULL,
2 * sizeof(uint32_t), // Space for 16 instructions. (More than enough.)
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS,
-1,0);
if (ret == MAP_FAILED) {
printf("Could not mmap a memory buffer with the proper permissions.\n");
return -1;
}
*(ret + 0) = 0xE2800001; //add r0 r0 #1 := r0 += 1
*(ret + 1) = 0xE12FFF1E; //bx lr := jump back to inc()
__clear_cache((char*) ret, (char*) (ret+2));
int(*f)(int) = (int (*)(int)) ret;
return (*f)(x);
}
int main(){
printf("%d\n",inc(6)); //expect '7' to be printed
exit(0);}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.