2010-04-26 6 views
4

this ARM 어셈블리 프로그램 (페이지 하단 참조)을 수정하여 서브 루틴을 사용하려고했습니다. GBA에 빨간색 화면이 표시되어야합니다. (예를 들어 도구 상자 사용 문제가 아니기 때문에 실제로 실행되는 예제 프로그램을 컴파일해야합니다.) 그러나 실행할 때 화면이 검은 색으로 변합니다. devkitARM을 사용하고 있습니다. 30GBA ARM 어셈블리 프로그램에 대한 도움말

.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 

이 프로그램의 문제점은 무엇입니까?

답변

3

나는 혼자 해결했다.

문제는 내가 스택을 사용하는 방식이었습니다. stmdbldmdb 대신 stmfdldmfd을 사용해야했습니다.

+0

과 비슷합니다. 그게 효과가없는 이유를 이해 하죠? –

+1

스택 포인터가 밀고 내릴 때 모두 내려 가기 때문에 예, 그렇다고 생각합니다. 그래? –

+0

정확히 맞습니다. 'stmfd'는'stmdb'와 같고'ldmfd'는'ldmia'와 같습니다. 나는 개인적으로 그것들을 그렇게 생각하는 것을 더 쉽게 찾는다. –

0

stmdb는 감소하기 전에 해당 주소를 사용하여 스택에 쓰기를 시작하는 것이 적절합니다. ldmia는 이후의 증분을 의미하므로 현재 스택 포인터로 시작하여 값을 레지스터로 다시 읽은 다음 스택 포인터를 증가시킵니다. fd 명명법은 결코 나에게 이해가되지 않았다. 동일하게 점프하고 0이 모든 프로세서에 대해 동일한 명령어이고 일부 ASM이 둘 다 제공하는 경우 점프와 마찬가지로 ldm과 stm의 두 가지 맛이 있습니다. db, ia, fd는 모두이 두 가지 맛으로 매핑됩니다. 나는 (ldmia) 이후에 증분을 기억하고 (ldmdb) 전에 감소시키는 것이 더 쉽다는 것을 알았다. 또는 어떤 이유로로드/저장 방향 비트를 돌리면 수행하려는 작업에 따라 이전 또는 이후에 올바른 증가를 선택합니다.

C에서는 * (ptr ++) vs * (++ ptr)

관련 문제