2010-12-06 39 views
3

J'ai donc pris la programmation d'assemblage. C'est assez simple sur ma boîte Ubuntu: en utilisant NASMamd GNU ld, j'ai pu écrire des programmes de style HelloWorld plus ou moins compliqués en une demi-heure. Mais quand il s'agit de l'iPhone, c'est tellement compliqué. Tout d'abord, j'ai un firmware JB'en iPhone 3G sur 4.2.1, ce qui signifie que j'utilise le port ARM du Darwin kernel v10. Deuxième. Je dois utiliser GNU comme, car il n'y a pas de NASM pour iPhone: la chaîne d'outils native (à la fois Xcode sur Mac OS X et opensource sur Linux) utilise GCC. Donc, j'ai rassemblé des informations de base sur: - comment écrire l'assembly dans GNU comme langue; - quelles sont les instructions de base ARM, registres, accès à la mémoire.ARM Darwin assembly - à la recherche d'appels système (tutoriel peut-être)

Mais même HelloWorld requiert des appels de noyau pour écrire sur stdout. Ma question est: quel appel du noyau à utiliser et comment (quels arguments vont où); Je devrais utiliser l'instruction swi # ARM, ne devrais-je pas? Alors, pouvez-vous s'il vous plaît poster quelques informations/liens vers des tutoriels, ou quelqu'un avec un code ARM Darwin Bonjour monde ARM?

A partir de maintenant, je pouvais le faire:

;Hello World for Linux and NASM 
section data 
hello db "Hello World" 
helloLen equ $ - hello 

section text 
global _start 
_start: 
    mov eax, 4 ; sys_write 
    mov ebx, 1 ; to stdout 
    mov ecx, hello ; address of string 
    mov edx, helloLen ; value (because of eq!!!) of strLen 
    int 0x80 ; call awesome Linux kernel 

    mov eax, 1 ; sys_exit 
    mov ebx, 0 ; "return 0; " if you like C 
    int 0x80 ; call kernel to end program 

sur ARM, cependant, je ne pouvais le faire comme ceci:

.text 
start: 
    mov r0, #0 
    mov r1, #234 
    add r2, r0, r1 
@all mov and add and other stuff works fine 
    swi #0xc00 
@all that I get is Bad system call error 

Alors, tout le monde s'il vous plaît?

+2

Une bonne chose que vous pouvez faire est de lancer GCC avec le drapeau S, qui donnera vous sortie d'assemblage que vous pouvez regarder pour voir comment il le fait. –

+0

Merci, malheureusement j'ai essayé ceci, mais je n'ai obtenu que du code assez "obfusqué" ce qui référençait _printf dans libgcc. Puis-je utiliser la fonction __asm ​​__() C pour convertir l'ASM de style Intel en code ARM? (Je vais essayer). – H2CO3

Répondre

1

Voilà comment libc (libSystem) le fait:

; ssize_t read(int, void *, size_t) 
       EXPORT _read 
_read 
       MOV  R12, #3   ; SYS_read 
       SVC  0x80 ; 'А'  ; do a syscall 
       BCC  _ok    ; carry clear = no error 
       LDR  R12, =(cerror_ptr - . - 8) ; otherwise call error handler 
       LDR  R12, [PC,R12] ; load pointer 
       B  _call_error 
       DCD cerror_ptr - . 
_call_error        
       BX  R12 ; cerror ; jump to it (error number is in R0) 
_ok 
       BX  LR    ; return to caller 
; End of function _read 

i.e. .:

  1. numéro d'appel système est en R12 (voir sys/syscall.h).
  2. L'instruction d'appel système est SVC 0x80 (SWI 0x80).
  3. D'autres paramètres sont conformes à l'ABI (R0-R3, puis pile).
  4. En cas d'erreur, l'indicateur de retenue est défini et le numéro d'erreur est renvoyé dans R0.