我试图为Raspberry Pi B +版本编写一个非常基本的交叉编译器来构建简单的裸机程序。我的编译器能够使用ARM指令集数据表将简单命令转换为相应的机器语言指令。
打开LED(定位于烘焙程序,http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/)可以正常工作。
但现在我想做一些分支指令,而这似乎没有任何东西可以工作了:
首先,我想分支到绝对地址,没有使用B / BL指令的相对分支。
为了测试分支,我使用以下反汇编代码(使用Hopper Disassembler V3测试版拆卸),打开与GPIO 16和22连接的LED:
C-v jjjj $
现在我想在代码的开头添加一个分支,跳过第一部分,以便只激活第二个LED。
我尝试过这样:
00000000 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
00000004 orr r0, r0, #0x200000
00000008 mov r1, #0x40 ;Load the Set Function Mask (for GPIO 22) into r1
0000000c str r1, [r0, #0x8] ;Store the Set Function Mask into the GPFSEL2
00000010 mov r1, #0x400000 ;Move the Set Output Mask (for GPIO 22) into r1
00000014 str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000018 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
0000001c orr r0, r0, #0x200000
00000020 mov r1, #0x40000 ;Load the Set Function Mask (for GPIO 16) into r1
00000024 str r1, [r0, #0x4] ;Store the Set Function Mask into the GPFSEL2
00000028 mov r1, #0x10000 ;Move the Set Output Mask (for GPIO 16) into r1
0000002c str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000030 b 0x30 ;Infinity Loop to keep the processor up
但唯一的影响是两个LED都保持黑暗。
我的第二次尝试是这样的:
mov r15, #0x1c
但这都不起作用。
所以我的问题是:
答案 0 :(得分:1)
Bx或blx应该是您指示的第一选择。你可以进入电脑,但为什么要设置寄存器,推送和弹出,只需bx。并且可能有一些其他人可以正确修改电脑,不确定mov是否只有一个,但是文档会告诉你。
如果bx不适合您,那么您要么编码错误的bx,要么您没有将地址放在正确的寄存器中。
mov r3,#0x12000000
orr r3,r3,#0x00340000
orr r3,r3,#0x00005600
orr r3,r3,#0x00000078
bx r3
产生
0: e3a03412 mov r3, #301989888 ; 0x12000000
4: e383370d orr r3, r3, #3407872 ; 0x340000
8: e3833c56 orr r3, r3, #22016 ; 0x5600
c: e3833078 orr r3, r3, #120 ; 0x78
10: e12fff13 bx r3
并将分支到地址0x12345678
答案 1 :(得分:0)
您分支到错误的地址,您的程序加载到0x8000。如果使用标签,链接器应为您计算地址。
答案 2 :(得分:0)
虽然我不知道Raspbery Pi寄存器,但我认为此代码中存在一些问题:
顺便说一下,延迟的for循环可能是这样的:
MOV r0, #1000 ; Start of the counter
loop: SUBS r0, #1 ; Decrement the counter (Sets the flags for the branch)
BNE loop ; Branch to loop label until r0 is 0
答案 3 :(得分:0)
感谢来自@TimothyBaldwin的提示,我现在得到了答案(我希望如果我写一个自己的答案提供更多细节而不是简单地接受他的答案就可以了。)
如@TimothyBaldwin所述,问题是程序加载在0x8000,正如您在https://raspberrypi.stackexchange.com/questions/10442/what-is-the-boot-sequence找到的图表中所见。
正如那里所解释的那样,在我的情况下,如果我在config.txt中添加以下行,它的效果非常好:
disable_commandline_tags=1
因为然后代码加载到0x0,一切都按预期工作。