2013-06-28 16 views
5

Próbuję wydrukować numer, który zapisałem. Nie jestem pewien, czy jestem blisko, czy daleko. Każda pomoc będzie jednak doceniona. Oto mój kod:Jak wydrukować numer w zespole ARM?

.data 
.balign 4 
a: .word 4 

.text 
.global main 
main: 
     ldr r0, addr_of_a 
     mov r1, #8 
     str r1, [r0] 
write: 
     mov r0, #1 
     ldr r1, addr_of_a 
     mov r2, #4 
     mov r7, #4 
     swi #0 
     bx lr 

addr_of_a: .word a 

Kompiluje się i działa, ale nie widzę niczego wydrukowanego. Z tego co rozumiem, potrzebuję adresu gdzie zacząć drukować w r1, ile bajtów w r2, deskryptora pliku w r0, i r7 określa wywołanie zapisu, jeśli jest ustawione na # 4. Próbuję po prostu zapisać # 8, a następnie wydrukować zapisany numer.

+3

trzeba konwertować liczby na ciąg znaków (np ' 123' -> '" 123 "') najpierw. – Michael

Odpowiedz

4

Zapis syscall przyjmuje drugi argument (r1) wskaźnik do łańcucha, który chcesz wydrukować. Podajesz do niego wskaźnik do liczby całkowitej. Dlatego nic nie drukuje, ponieważ nie ma znaków ASCII w regionie pamięci, który do niego przechodzisz.

Poniżej znajduje się program "Hello World" z wykorzystaniem zapisu syscall.

.text 
.global main 
main: 
     push {r7, lr} 

     mov r0, #1 
     ldr r1, =string 
     mov r2, #20 
     mov r7, #4 
     svC#0 

     pop {r7, pc} 

.data 
string: .asciz "Hello World\n" 

Jeśli chcesz wydrukować numer, możesz użyć funkcji printf z biblioteki C. Tak:

.text 
.global main 
.extern printf 
main: 
     push {ip, lr} 

     ldr r0, =string 
     mov r1, #1024 
     bl printf 

     pop {ip, pc} 

.data 
string: .asciz "The number is: %d\n" 

Wreszcie, jeśli chcesz drukować numer z zapisu syscall można również realizować funkcję itoa (jeden, który konwertuje liczbę całkowitą na łańcuch).

+1

Szukałem odpowiedzi na temat konwersji liczby całkowitej na char w zespole ARM. Wszystkie wyniki otrzymam wyjaśnić, jak to zrobić w C jednak. Jak chciałbym wykonać tę konwersję w ARM bez bibliotek C? –

+0

Pamiętaj, że znaki nie są niczym więcej niż cyframi w kodzie ASCII. Liczba 48 odpowiada znakowi "0" w ASCII. Liczba 49 do "1" i tak dalej. Jeśli chcesz przekonwertować liczbę całkowitą na znak, to możesz dodać 48 do liczby całkowitej, a następnie zapisać wynik jako bajt (a nie jako liczbę całkowitą, ponieważ int ma 4 bajty) w pewnym miejscu pamięci. Następnie, jeśli wyślesz wskaźnik tej lokalizacji pamięci do zapisu syscall, wydrukuje on znak. –

3

Witam Doceniam, że jest to całkiem stara nitka, ale przez chwilę podrapałem się w głowę i chciałbym podzielić się moim rozwiązaniem. Może to pomoże komuś po drodze!

Chciałem drukować na cyfrę bez uciekania się do używania C++ w jakikolwiek sposób, choć zdaję sobie sprawę, że po prostu dekompilacja tostringa() - lub jakikolwiek odpowiednik istnieje w C++ - i zobaczenie, co to było, byłoby daleko. szybsza trasa.

W zasadzie skończyłem z utworzeniem wskaźnika na pusty ciąg .ascii w sekcji .data i dodałem cyfrę, którą chciałem wydrukować + 48 przed wydrukowaniem tej cyfry.

Firma +48 ma oczywiście na myśli numer indeksu ASCII określonej cyfry.

.global _start 

_start: 
MOV R8, #8 
ADD R8, R8, #48 

LDR R9, =num 
STR R8, [R9] 

MOV R0, #1 
LDR R1, =num 
MOV R2, #1 
MOV R7, #4 
SWI 0 

.data 

num: 
.ascii: " " 

Największą wadą tego podejścia jest to, że nie obsługuje on oczywiście liczby większej niż jedna cyfra.

Moje rozwiązanie to było dużo, dużo brzydsze i wykracza poza zakres tej odpowiedzi tutaj, ale jeśli masz silny żołądek można to zobaczyć here:

+0

Wiele asemblerów pozwala używać stałych ASCII w wyrażeniach, np. '# '0'' zamiast' # 48'. IDK, jeśli pozwala na to Asembler ARM, ale '0'' działa z asemblerem GNU dla x86. Ponadto, nie trzeba inicjować '.ascii', ponieważ nie czyta się go przed napisaniem. –

+0

Miło wiedzieć. Sprawdzę to, zaoszczędziłbym trochę kłopotu! – Tombas