[英]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.