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
相关产品推荐
相关产品推荐

