2012-04-18 2 views
1

ARM 어셈블러로 작성된 간단한 함수가 있습니다. 처음 실행하면 모든 것이 원하는대로 작동합니다 (BOOT\n). 그러나 두 x 째 기능이 실행될 때 아무 것도 인쇄되지 않습니다.ARM 어셈블리 기능에 문제가 있습니까?

.globl __printTest 
.text 
.align 2 

__printTest: 
sub sp, #64 /* yes, I know this is too much */ 

mov r0, #66 
str r0, [sp] 
mov r0, #79 
str r0, [sp, #1] 
mov r0, #79 
str r0, [sp, #2] 
mov r0, #84 
str r0, [sp, #3] 
mov r0, #10 
str r0, [sp, #4] 

mov r0, #0 
mov r1, sp 
mov r2, #5 

bl _write 
add sp, #64 

bx lr 

무엇이 문제 일 수 있습니까? 나는 이것이 어떻게 든 더 이상 작동하지 않는 버퍼를 망가 뜨리는 것으로 의심한다. 쓰기는 svc 명령어를 사용하여 Linux에서 write 시스템 호출을 호출하는 함수입니다.

답변

4

문제는 당신이 lr을 저장하지 않는다는 것입니다.

 bl _write 
    add sp, #64 
    bx lr 

bl _write

add sp, #64에 다음을 가리키는 lr을 덮어 쓰게됩니다, 그래서 당신의 bx lr은 마지막 두 지시에 무한 루프가 발생합니다. 마찬가지로 이미 다른 답변에 명시된

__printTest: 
push {lr} 
sub sp, #64 /* yes, I know this is too much */ 
.... 
bl _write 
add sp, #64 
pop {pc} 

, 당신은 또한 바이트 저장을위한 STRB 대신에 캐릭터 라인을 사용한다 :이 같은 코드를 수정하면

그것은 작동합니다.

+0

고마워요! 이것은 효과가 있었다. –

3

이 함수는 32 비트 값을 정렬되지 않은 스택 포인터 주소로 푸시합니다. 단일 바이트를 쓰려면 strb을 사용해야합니다. 정렬되지 않은 str 내용은 ARM 아키텍처 참조 문서는 말한다 :

if UnalignedSupport() || address<1:0> == ‘00’ then 
    MemU[address,4] = R[t]; 
else // Can only occur before ARMv7 
    MemU[address,4] = bits(32) UNKNOWN; 

그래서 당신이 알 수없는 경우를 타격하는 경우, 당신은 당신의 스택에 쓰레기를 받고있을 수 구성에 따라 달라집니다.

+0

'str's를'strb's로 대체했습니다. 여전히 같은 문제. –

관련 문제