我试图修改 ARM组装程序(请参阅页面底部)使用子例程。它应该在GBA上显示红色屏幕(并编译实际执行的示例程序,因此它不是工具链使用问题),但是,当我运行它时,屏幕会变黑。我正在使用Devkitarm 30

.arm
.text
.global main
main:
    mov r0, #0x4000000
    mov r1, #0x400
    add r1, r1, #3
    str r1, [r0]
    mov r0, #0x6000000
    stmdb sp!, {r0, r2, lr} @push registers before calling
    mov r0, #0xff
    mov r1, #0
    mov r2, #0
    bl set_rgb
    mov r1, r0
    ldmdb sp!, {r0, r2, lr} @restore registers
    mov r2, #0x9600
loop1:
    strh r1, [r0], #2
    subs r2, r2, #1
    bne loop1
infin:
    b infin

set_rgb:
    @r0: R; r1: G; r2: B; r0: RGB

    @truncate everything but the least significant five bits
    and r0, r0, #0x1f
    and r1, r1, #0x1f
    and r2, r2, #0x1f
    @form the color
    orr r0, r0, r1, lsl #5
    orr r0, r0, r2, lsl #10
    mov pc, lr @return

问题是,该程序中有什么问题?

有帮助吗?

解决方案

我自己解决了。

问题是我使用堆栈的方式。代替 stmdbldmdb 我需要使用 stmfdldmfd.

其他提示

STMDB意味着在前后使用该地址开始写入堆栈,这是正确的。 LDMIA意味着在此之后进行增量,因此从当前的堆栈指针开始,将值读回其寄存器,然后递增堆栈指针。 FD命名法对我来说从来没有意义。像跳跃时一样,如果零是所有处理器的指令,并且有些ASM都提供了同时提供的指令,那么LDM和STM只有两种口味DB,ia,fd都映射到这两种口味中。我发现(LDMIA)和(ldmdb)之前的增量更容易记住。或者,如果由于某种原因将负载/存储方向转动,则仍然根据要做的事情在之前或之后选择正确的增量。

在c中,就像 *(ptr ++)vs *(++ ptr)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top