首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从C调用机械臂组件,GCC (裸机)

从C调用机械臂组件,GCC (裸机)
EN

Stack Overflow用户
提问于 2012-01-22 07:02:31
回答 4查看 9K关注 0票数 8

我正在尝试和GCC一起在ARM上做一些裸机编程,并在QEMU上进行测试。每当我从C调用ARM标签时,我的程序就会挂起。我有一个简单的代码示例,它显示了https://gist.github.com/1654392的问题--当我在代码中调用activate()时,它挂起了。

我用objdump观察到,当我从汇编到C代码(如从_start)执行bl时,它会生成一个切换到thumb指令的小包装器。似乎所有的C代码都是在thumb指令中生成的,但我的所有汇编都是在ARM (32位)指令中生成的。我不知道这是为什么,也不知道如何修复它。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-20 15:13:39

为了从C定义的THUMB模式函数调用汇编语言中定义的ARM模式函数,您需要将汇编语言中的符号定义为函数,并且工具(Linaro gcc)将生成blx指令而不是bl指令。

示例:

代码语言:javascript
复制
@ Here, we suppose that this part of code is inside of .code 32

.type fn, %function

fn:
   mov  pc, lr
票数 7
EN

Stack Overflow用户

发布于 2012-01-22 23:43:55

请参见http://github.com/dwelch67/yagbat qemu目录。

下面是几个从arm调用arm或thumb的示例

代码语言:javascript
复制
start_vector:
    mov sp,#0x20000
    ;@ call an arm function from arm
    bl notmain

    ;@ call a thumb function frm arm
    ldr r0,=0xAABBAABB
    bl hexstring_trampoline

    ;@ call a thumb function frm arm
    ldr r0,=0x12341234
    ldr r1,hexstring_addr
    mov lr,pc
    bx r1

    ;@ call a thumb function frm arm
    ldr r0,=0x12312344
    bl hexstring_trampoline

hang:
    b hang

hexstring_trampoline:
    ldr r1,hexstring_addr
    bx r1

hexstring_addr: .word hexstring

如果您查看指令集参考,您将看到您需要使用BX或BLX在arm和thumb状态之间切换。BLX不像BX那样被广泛支持。

从程序计数器的定义角度来看,pc在指令执行期间领先两条指令。对于thumb是4字节,对于arm是8字节。无论哪种情况,都有两条指令。要模拟不能用于更改状态的bl,您需要用返回地址加载链接寄存器,并使用bx根据地址的lsbit分支到函数更改状态。因此,

代码语言:javascript
复制
mov lr,pc
bx r1
here:

上面的mov lr,pc加载这里的地址:这是我们的返回地址,bx r1以独立于状态的方式调用函数。lr地址的lsbit指示要返回的模式,您需要始终使用bx返回

代码语言:javascript
复制
pre_thumb:
ldr pc,lr

thumb_capable:
bx lr

编译器分配bl指令来调用函数,链接器随后填充其余部分,如果太远,则需要链接器自己添加的trampoline函数。同样,如果您需要更改模式,bl将调用一个执行此操作的trampoline函数。我已经在上面的一个例子中模拟了这一点,你可以看到它有点浪费,希望我对编译器只为bl分配空间的解释让这一点变得更清楚,浪费就是总是计划模式更改,并且必须在代码中为大多数函数调用插入nops。

代码还包括在汇编程序中从thumb调用arm:

代码语言:javascript
复制
.thumb

.thumb_func
.globl XPUT32
XPUT32:
    push {lr}
    ;@ call an arm function from thumb asm
    ldr r2,=PUT32
    mov lr,pc
    bx r2
    pop {r2}
    bx r2

大体相同,除了你不能弹出lr在拇指模式,你可以弹到pc,但我不认为切换模式,所以你不能使用它,你再次需要一个备用寄存器。当然,您需要了解调用约定以了解您可以使用哪些寄存器,或者您可以包装另一组推送和弹出以保留除lr之外的所有寄存器

代码语言:javascript
复制
    push {r2,lr}
    ;@ call an arm function from thumb asm
    ldr r2,=PUT32
    mov lr,pc
    bx r2
    pop {r2}
    mov lr,r2
    pop {r2}
    bx lr

拇指对拇指或手臂对手臂如果你够得着就用bl。ldr pc,如果不能,请提供地址。

票数 3
EN

Stack Overflow用户

发布于 2012-01-23 19:30:44

如果您将asm代码汇编为Thumb,则需要将函数标记为Thumb函数,以便链接器在分支到它时使用正确的指令(例如,BLX或BX到设置了低位的地址)。这是通过.thumb_func指令完成的:

代码语言:javascript
复制
.global activate
.thumb_func
activate:
    b test

另一种选择是显式地要求汇编程序生成ARM代码:

代码语言:javascript
复制
.code 32
.global activate
activate:
    b test

也要检查this article,尽管请记住,当前的处理器不需要很多在ARMv4中必需的变通方法,因此您可能不应该盲目地遵循它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8957474

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档