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

ARMv8汇编提取系统调用为子例程触发非法指令问题求助

ARMv8汇编提取系统调用子例程触发Illegal Instruction错误的解决方法

问题原因

提取的GetTermSize子例程缺少返回指令。使用bl调用子例程时,ARMv8会将返回地址存入x30(LR寄存器),但原子例程执行完系统调用后,没有跳回x30指向的地址,而是继续执行后续的非法指令,最终触发错误。ARMv8汇编子例程必须以ret指令结束,才能正确返回到调用者的下一条指令。

修正后的子例程代码

GetTermSize:
    mov x0, #1
    mov x1, #0x5413
    ldr x2, =termsize
    mov x8, #29
    svc #0
    ret  ; 关键:添加这条返回指令,回到main的调用位置

完整修正代码示例

将原main中的系统调用代码替换为bl GetTermSize,并加入修正后的子例程:

.global main

.section .text
.align 2

main:
    ldr x0, =termtitle
    bl printf
    
    bl initscr
    mov x0, #0
    bl curs_set
    bl refresh
    
    adrp x9, court
    add x9, x9, :lo12:court
    
    bl GetTermSize  ; 调用提取后的子例程
    
    ldr x19,=termsize
    
    mov x0, #10
    mov x1, #30 
    ldr w4, [x19,#0]
    mov x5, #2      
    udiv w2, w4, w5
    sub x2, x2, #5
    ldr w4, [x19,#2]
    mov x5, #2
    udiv w3, w4, w5
    sub x3, x3, #15
    bl newwin       
    str x0, [x9] 
    
    ldr x0, [x9]

    sub sp, sp, #16
    str x0, [sp]

    mov x1, #0
    mov x2, #0
    bl box

    
    adrp x9, court
    add x9, x9, :lo12:court
    
    ldr x0, [x9]
    mov x1, #5
    mov x2, #5
    ldr x3, =prototype
    bl mvwprintw
    
    
    ldr x0, [sp]
    add sp, sp, #16
    
    bl wrefresh

    bl getch
    bl endwin

    mov x8, 93
    mov x0, 0
    svc 0

; 修正后的子例程
GetTermSize:
    mov x0, #1
    mov x1, #0x5413
    ldr x2, =termsize
    mov x8, #29
    svc #0
    ret

.section .data
termsize: .skip 4
termtitle: .asciz "\033]0;ARMv8 - Ncurses Bouncing Ball\007"
court:  .quad 0
ball:
    .byte 0
    .byte 0
    .byte 0x4F
prototype: .asciz "o"

补充说明

  • ret指令的作用是跳转到x30寄存器保存的返回地址,这是ARMv8子例程返回调用者的标准方式。
  • 确保子例程和main位于同一个.text段,并且保持.align 2的对齐要求(ARMv8指令为4字节长度,4字节对齐可避免执行异常)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 07:33:19