2016-07-11 12 views
0

Ich habe Beispiele von Menschen gesehen aus der C-Bibliothek in ihrem Code mit printf wie so:mit einer C-Funktionen mit ARM-Baugruppe

.data 
.balign 4 
hello: .asciz "Hello\n" 

.text 
.global main 
.func main 

main: 
    ldr r0, hello_msg 
    bl printf 
    mov r7, #1 
    swi 0 
hello_msg: .word hello 
.global printf 

Wie haben sie r0 heraus als String arg übergeben werden würde printf? Ich weiß, dass r0-r3 als Argumente übergeben werden, wenn eine Subroutine aufgerufen wird, aber ich weiß nicht, welches Register zu welchem ​​Argument gehört. Beispiel: Wenn scanf verwendet wird, ist r0 die Formatierung der Zeichenfolge und r1 speichert die Benutzereingabe. Wie sollen wir das wissen? Meine einzige Vermutung ist, meine * .s-Datei mit gcc mit der Option -S zu kompilieren und die zusammengestellte Datei anzuzeigen ... aber gibt es einen besseren Weg?

+2

Ja gefunden haben, können Sie auf dem ABI lesen, dass die C-Bibliothek verwendet ... – Notlikethat

+0

ich bereits am [ABI ausgesehen haben für ARM] (http://infocenter.arm.com/help/topic/com.arm.doc.dui0371l/DUI0371L_mxscript-v1-3-for-fast-models_reference-manual.pdf) und erwähnt nichts Register. Außerdem war es das einzige C Library ABI, das ich finden konnte. Wo finde ich ABIs, die angeben, wie jedes Register verwendet wird? – Tyler

+1

Es ist Teil des Eabi oder Abi für Arm. vielleicht schaust du nicht auf den richtigen Ort. Am Ende des Tages ist der Compiler richtig, wenn es um nichts anderes geht, als mit sich selbst zu reden, also eine einfache C-Funktion erzeugen, sie von einer anderen einfachen C-Funktion aufrufen, und für diesen Compiler sind die von ihm gewählten Register die richtigen. Nun, wenn Sie beginnen, Dinge wie 64-Bit-Variablen oder Gleitkomma zu tun, kann die Register/Stack-Verwendung nichtlinear werden (sie könnten z. B. r1 oder r3 überspringen). Einfach neu prototypieren und nachahmen. –

Antwort

0

Ich werde versuchen zu erklären, was ich gelernt habe. Das einzige Linux, das ich habe, ist Raspbian Jessie (Raspberry Pi 3). Es gibt eine Datei /usr/include/arm-linux-gnueabihf/asm/unistd.h (irgendwo anders sollte Linux unistd.h haben), die define für in Linux eingebaute Funktionen zeigt [ex: #define __NR_write (__NR_SYSCALL_BASE + 4)]. Betrachten Sie Linux Man Seite http://man7.org/linux/man-pages/man3/write.3p.html im Format.

 ssize_t write(int fildes, const void *buf, size_t nbyte) 
return in r0 [4] (  r0 ,   r1 ,  r2 ) 

Ich bin irgendwie neu hier, also habe ich ein Programm aufgenommen, das mir hilft, es zu verstehen. Siehe auch http://man7.org/linux/man-pages/dir_by_project.html#man-pages für andere Formate.

@---------------------------------- 
@ asfileio.s 
@ 
@ Raspbian Jessie assembly program using 
@ SVC for file operations on Raspberry Pi 3 
@ 
@ [email protected]:~/Programs $ as -o asfileio.o asfileio.s 
@ [email protected]:~/Programs $ gcc -o asfileio asfileio.o 
@ [email protected]:~/Programs $ ./asfileio; echo $?; ls -l /tmp/test* 
@ Hello world 
@ A quick brown fox jumped over the lazy dog. 
@ 0 
@ -rw-r--r-- 1 pi pi 26 Jun 18 14:58 /tmp/testfile01.txt 
@ -rw-r--r-- 1 pi pi 45 Jun 18 14:58 /tmp/testfile02.txt 
@ [email protected]:~/Programs $ 
@---------------------------------- 
@ 
@ http://man7.org/linux/man-pages/dir_by_project.html#man-pages 
@ 
@ CREATE int creat(const char *pathname, mode_t mode); 
@    Mode rwx {owner, group, other} 
@ OPEN int open(const char *pathname, int flags); 
@    Flags O_RDONLY, O_WRONLY, or O_RDWR 
@     | O_APPEND 
@ READ ssize_t read(int fd, void *buf, size_t count); 
@ WRITE ssize_t write(int fd, const void *buf, size_t count); 
@ CLOSE int close(int fd); 
@ SYNC void sync(void); 
@ EXIT void _Exit(int status); 
@ 
@---------------------------------- 

.data 

@ See /usr/include/arm-linux-gnueabihf/asm/unistd.h 
@ See /usr/include/arm-linux-gnueabihf/bits/fcntl-linux.h 

    .equ create,  8 
     .equ Mode, 0644  @ -rw-r--r-- 
    .equ open,  5 
     .equ Rd, 00 
     .equ Wr, 01 
     .equ RdWr, 02 
     .equ Apnd, 02000 
    .equ read,  3 
    .equ write,  4 
    .equ close,  6 
    .equ sync,  36 
    .equ exit,  1 
    .equ sfile,  187 

@---------------------------------- 

.balign 4 
Create: 
    .word dir_file, Mode, create 

.balign 4 
Open: 
    .word dir_file, RdWr | Apnd, open 

.balign 4 
Write: 
    .word data, after_data - data, write 

.balign 4 
Write2: 
    .word data2, after_data2 - data2, write 

.balign 4 
Read: 
    .word Buf, 80, read 
.balign 4 
Buf: 
    .space 80 

@---------------------------------- 

data: 
.asciz "Hello world\n" 
after_data: 

.balign 4 
data2: 
.asciz "A quick brown fox jumped over the lazy dog.\n" 
after_data2: 

.balign 4 
dir_file: 
.asciz "/tmp/testfile01.txt" 

@---------------------------------- 

.text 

.global main, _start 

@_start:      @ Uncommit if using ld as linker 
main: 

     push {r4, r5, r7, lr} 
     b  M_Program 

S_Write:  @ err 4 if error @ subroutine or function 
@ System call to write to file (or stdout) 
@ Write amt_wrote=(write(fd, &data, sizeof(data))) 
@    r0=(r7=4( r0, r1=&data, r2=len(data))) 

     ldr r3, =Write  @ address of parameters 
S_Write2: 
     ldm r3, {r1, r2, r7} @ load write parameters 
     svc #0    @ Linux kernel writes 
     cmp r0, r2   @ check amt = len 
     movne r0, #4   @ set error code to 4 
     bne exit    @ exit if error 
     mov r0, #0   @ success 
     mov pc, lr   @ return to program 

S_Create: @ err 8 if error 
@ Create fd=(creat( &dir_file, -rw-r--r--)) 
@   r0=(r7=8 (r0=&dir_file, r1=0644)) 

     ldr r3, =Create 
     ldm r3, {r0, r1, r7} 
     svc #0 
     mov r4, r0   @ save fd in r4 
     cmp r0, #3   @ err if < 3 
     movlt r0, #8 
     blt exit 
     mov r0, #0 
     mov pc, lr 

S_Open:  @ err 5 if error 

     ldr r3, =Open 
     ldm r3, {r0, r1, r7} 
     svc #0 
     mov r4, r0 
     cmp r0, #3 
     movlt r0, #5 
     blt exit 
     mov r0, #0 
     mov pc, lr 

S_Close:  @ err 6 if error 

     mov r7, #close 
     svc #0 
     cmp r0, #0 
     movne r0, #6 
     bne exit 
     mov pc, lr 

S_Read: 

     ldr r3, =Read 
     ldm r3, {r1, r2, r7} 
     svc #0 
     mov pc, lr 

M_Program: 

@ S_Write call to write to stdout 

     mov r0, #1   @ fd=1=stdout 
     bl  S_Write 

@ Create, write and close file in /tmp 

     bl  S_Create   @ create file 
     mov r0, r4   @ move fd to r0 
     bl  S_Write   @ write to file 
     mov r0, r4   @ move fd to r0 
     bl  S_Close   @ close the file 

@ Open same file for write append 

     bl  S_Open   @ open file 
     mov r0, r4   @ move fd to r0 
     bl  S_Write   @ write to file 
     mov r0, r4   @ move fd to r0 
     bl  S_Close   @ close file 

@ Change variables for new file 

     ldr r3, =dir_file 
     add r3, #12 
     ldr r2, [r3] 
     eor r2, #0x30000 
     str r2, [r3] 

@ Create new file, write and close 

     bl  S_Create 
     mov r0, r4 
     ldr r3, =Write2 
     bl  S_Write2 
     mov r0, r4 
     bl  S_Close 

@ Open file, read, write to stdout and close 

    bl  S_Open 
    mov  r0, r4 
    bl  S_Read 

    mov  r2, r0   @ r0 has amt read 
    mov  r0, #1   @ fd = 1 = stdout 
    ldr  r1, =Buf   @ addr data just read 
    mov  r7, #write 
    svc  #0 
    mov  r0, r4 
    bl  S_Close 

exit: 

     pop {r4, r5, r7, lr} 
     bx  lr    @ Exit if use gcc as linker 
@  mov r7, #1   @ Exit if use ld as linker 
@  svc #0    @ Exit if use ld as linker 

Die besten docs, die ich auf dem Arm Register sind http://caxapa.ru/thumbs/656023/IHI0042F_aapcs.pdf Seite 14.