You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QEMU for AArch64:执行卡在ldr q1, [x0]导致yyy未打印的原因

问题:为何ldr q1, [x0]导致程序无法打印yyy?

代码与环境

C代码

#include "uart.h"
#include <string.h>
char x[32];
__attribute__((noinline))
void foo(void)
{
    strcpy(x, "xxxxxxxxxxxxxxxxxxxxxxxx");
}
int main(void)
{
  uart_puts("xxx\n");
  foo();
  uart_puts("yyy\n");
}

编译命令

$ aarch64-none-elf-gcc t78.c -mcpu=cortex-a57 -Wall -Wextra -g -O2 -c -std=c11 \
&& aarch64-none-elf-ld -T linker.ld t78.o boot.o uart.o -o kernel.elf

运行命令

$ qemu-system-aarch64.exe -machine virt -cpu cortex-a57 -nographic -kernel kernel.elf

问题现象

程序运行后仅输出xxx,后续的yyy完全没有打印。

排查情况

  • GCC并未生成调用strcpy函数的代码,而是将strcpy的逻辑内联到了foo函数中
  • 汇编代码里的ldr q1, [x0]指令是问题根源:在这条指令前添加ret让foo直接返回后,yyy可以正常打印

foo函数的汇编代码

foo:
.LFB0:
        .file 1 "t78.c"
        .loc 1 6 1 view -0
        .cfi_startproc
        .loc 1 7 5 view .LVU1
        adrp    x0, .LC0
        add     x0, x0, :lo12:.LC0
        adrp    x1, .LANCHOR0
        add     x2, x1, :lo12:.LANCHOR0
        ldr     q1, [x0]                     <<== 问题根源
        ldr     q0, [x0, 9]
        str     q1, [x1, #:lo12:.LANCHOR0]
        str     q0, [x2, 9]
        .loc 1 8 1 is_stmt 0 view .LVU2
        ret

工具版本

$ aarch64-none-elf-gcc --version
aarch64-none-elf-gcc.exe (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205

$ qemu-system-aarch64 --version
QEMU emulator version 7.2.0 (v7.2.0-11948-ge6523b71fc-dirty)

原因分析

这条ldr q1, [x0]指令触发了内存访问异常,导致程序直接崩溃,无法执行到后续的uart_puts("yyy\n"),具体原因如下:

  1. 字符串常量的存储位置:GCC会把字符串常量"xxxxxxxxxxxxxxxxxxxxxxxx"放在.rodata(只读数据段)中,adrp x0, .LC0和add x0, x0, :lo12:.LC0这两条指令就是计算该字符串在内存中的地址。
  2. 裸机环境的内存映射问题:在当前裸机项目中,链接脚本linker.ld可能没有将.rodata段正确映射到可访问的物理内存区域,或者启动代码(boot.o)没有配置MMU让CPU能正常访问该地址。
  3. 异常触发:当CPU执行ldr q1, [x0]尝试读取.rodata段的内容时,由于该地址不可访问,会触发数据中止异常。而项目中没有安装对应的异常处理程序,CPU会直接进入错误状态,程序停止运行。

当在ldr q1, [x0]前添加ret指令时,foo函数直接返回,不会执行任何内存读取操作,自然不会触发异常,程序就能继续执行main函数中foo()之后的代码,成功打印yyy。


内容的提问来源于stack exchange,提问作者pmor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:30:39