【问题标题】:Segmentation fault with ARM assembly code called by C programC程序调用的ARM汇编代码的分段错误
【发布时间】:2016-03-12 15:39:24
【问题描述】:

我正在尝试编写一个在 Beaglebone white 上调用外部汇编函数的基本 C 程序。

据我了解,分段错误是指程序尝试访问内存的非法部分,但我不明白这是如何发生的,因为我遵循了一个使用相同方法的示例。

这是调用汇编函数将输入的数字乘以 5 的主 C 程序:

/*-- C_mult_by_5.c*/

#include <stdio.h>

extern int mult_by_5(int number);

int main()
    {
        int number_read;
        int number_read_by_5;
        printf("Hey, type a number");
        scanf("%d", &number_read);

        number_read_by_5 = mult_by_5(number_read);
        printf("%d times 5 is %d\n\r", number_read, number_read_by_5);

        return(0);
    }

这里是用来执行操作的汇编代码:

/*-- mult_by_5.s*/

.data
.balign 4
return: .word 0

.balign 4
message : .asciz "Result: %d\n"

.text
.balign 4
.global printf
.global mult_by_5

mult_by_5:

ldr r1, address_of_return       /*r1 < address_of_return*/
str lr, [r1]                /* *r1 < lr*/

ldr r0, [r0]                    /*r0 < *r0*/

add r0, r0, r0, LSL #2          /*r0 < r0 + 4*r0*/
mov r1, r0                      /* r1 < r0 */

ldr r0, address_of_message      /*r0 < &message*/
bl printf                       /*call to printf*/

ldr lr, address_of_return       /*lr < &address_of_return*/
ldr lr, [lr]                /*lr < *lr*/
bx lr                   /*return from main using lr*/

address_of_return : .word return
address_of_message : .word message
.end

在代码运行过程中,链接寄存器是否发生了一些事情,导致它试图返回非法地址?

【问题讨论】:

  • 使用 GDB 或其他调试器单步执行,观察寄存器。请特别注意ldr r0, [r0] 的作用,当 r0 包含一个通过 按值... 传递的数字时
  • 为什么将 LR 存储在全局变量中而不是堆栈中?为什么 .text 部分是全局的,而不是 .bss?在弄乱它之前阅读并理解 ABI。

标签: c assembly arm beagleboneblack beagleboard


【解决方案1】:

试试,

/*-- mult_by_5.s*/

.text
.balign 4
.global printf
.global mult_by_5

mult_by_5:

add r1, r0, r0, LSL #2          /*r1 = r0 + 4*r0*/
ldr r0, =message                /*r0 < &message*/
b printf                        /*tail call printf */
message : .asciz "Result: %d\n"
.balign 4

.end

ARM link and frame pointer 上的这个问题也可能会有所帮助。通常,您可以将lr 推入/弹出堆栈,而不使用.data 或静态内存。堆栈数据结构非常适合函数调用,因此它内置于许多机器语言中。

另外,您可以查看what a compiler does

【讨论】:

    猜你喜欢
    • 2013-09-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    相关资源
    最近更新 更多