SuperH汇编嵌套分支调用问题排查及解决方法
SuperH汇编嵌套子例程调用问题及解决方法
我编写了一个用于在屏幕绘制像素的SuperH汇编子例程,寄存器约定如下:
- r3:x坐标
- r4:y坐标
- r5:像素颜色
子例程代码:
# r3: x coord # r4: y coord # r5: pixel color draw_pixel: mov.l frame_buffer_address, r0 mov.l screen_width, r6 mul.l r6, r4 sts macl, r4 add r4, r3 add r3, r0 mov r5, r1 mov.b r1, @r0 rts nop
直接从主程序分支调用该子例程时可以正常运行:
mov #20, r3 mov #50, r4 mov #10, r5 bsr draw_pixel nop
但从另一个子例程draw_rect中嵌套调用draw_pixel时出现异常(原本想绘制矩形,先测试单个像素功能):
draw_rect: mov #50, r3 mov #20, r4 mov #4, r5 bsr draw_pixel nop rts nop
主程序调用draw_rect的代码:
bsr draw_rect nop
代码逻辑和直接调用时完全一致,仅增加了一层子例程嵌套,推测问题出在嵌套分支调用的处理上,但不确定具体需要做什么额外操作。(注:当前使用立即值仅为测试,后续会改用变量)
解决方案
在draw_rect中调用draw_pixel前,先保存pr寄存器的值,调用完成后再恢复该寄存器:
修改后的draw_rect代码:
draw_rect: sts pr, r9 # 保存pr寄存器 mov #50, r3 mov #20, r4 mov #4, r5 bsr draw_pixel nop lds r9, pr # 恢复pr寄存器 rts nop
原因说明:SuperH架构中,bsr指令会将返回地址写入pr(程序计数器)寄存器。当在draw_rect中调用draw_pixel时,bsr draw_pixel会覆盖pr中原先保存的从draw_rect返回主程序的地址,导致draw_pixel执行完返回后,无法回到draw_rect继续执行,最终程序流程出错。因此需要在嵌套调用前保存pr,调用完成后恢复,确保每层子例程的返回地址不丢失。
内容的提问来源于stack exchange,提问作者gfdjjrtiejo
相关产品推荐
相关产品推荐

