====== Raspberry Pi ARM assembly ====== Hier sammle ich Kommandos die für Assembler auf dem Raspberry Pi notwendig/hilfreich sind. Ich gehe davon aus dass die Befehle direkt auf dem Raspberry Pi ausgeführt werden (oder halt via SSH). ===== Kommandos ===== ==== Mit "as" von Quelltext zu Objekt Code ==== Das Ergebnis ist dann noch nicht ausführbar und muss noch mit "ld" gelinked werden (oder alternativ gcc). as 002.asm -o 002.o file 002.o 002.o: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), not stripped ==== Linken ==== ld 002.o -o 002.elf alternativ: ("-nostdlib" da mein Quelltext bisher äußert simpel ist ;)) gcc 002.o -o 002.elf -nostdlib file 002.elf 002.elf: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped ===== Debug mit gdb ===== Notizen für die Benutzung von gdb ==== Breakpoint setzen ==== (gdb) break _start Breakpoint 1 at 0x10074 ==== Programm ausführen ==== (gdb) run Starting program: /home/pi/arm-assembly/002.elf Breakpoint 1, 0x00010074 in _start () ==== Programm disassemblen ==== (gdb) disass Dump of assembler code for function _start: => 0x00010074 <+0>: mov r7, #4 0x00010078 <+4>: mov r0, #1 0x0001007c <+8>: ldr r1, [pc, #36] ; 0x100a8 <_start+52> 0x00010080 <+12>: mov r2, #19 0x00010084 <+16>: svc 0x00000000 0x00010088 <+20>: mov r7, #3 0x0001008c <+24>: mov r0, #0 0x00010090 <+28>: ldr r1, [pc, #20] ; 0x100ac <_start+56> 0x00010094 <+32>: mov r2, #1 0x00010098 <+36>: svc 0x00000000 ==== Register ansehen ==== (gdb) info reg r0 0x0 0 r1 0x0 0 r2 0x0 0 r3 0x0 0 r4 0x0 0 r5 0x0 0 r6 0x0 0 r7 0x0 0 r8 0x0 0 r9 0x0 0 r10 0x0 0 r11 0x0 0 r12 0x0 0 sp 0xbefff360 0xbefff360 lr 0x0 0 pc 0x10074 0x10074 <_start> cpsr 0x10 16 fpscr 0x0 0 ==== Nächste Instruktion ==== (gdb) ni 0x0001007c in _start () (gdb) ==== gdbserver und remote==== Ich hatte in einigen Fällen STDOUT nicht in der gdb-cmd-Ausgabe (zumindes nicht, wie ich es erwartet hatte). In solchen Fällen hilft es das Programm über gdbserver zu starten gdbserver 127.0.0.1:12345 003.elf aaaabbb Listening on port 12345 Remote debugging from host 127.0.0.1 aaaabbb Nun steuert man das Programm remote via gdb target remote :12345 break _start cont ==== Umfangreichere gdb-Ansicht ==== Mein Favorit ist "lay regs" da es die Register, den disassembled Code und die Command-Box zeigt. (gdb) lay regs Wer dies gern nutzt, sollte es in der ~/.gdbinit hinterlegen. Mit "focus cmd" funktioniert dann der "Pfeil nach oben" auch wieder. Wer im ASM-Code navigieren möchte, setzt den "focus asm" oder "focus prev". ==== Speicher an einer bestimmten Stelle/Adresse inspizieren ==== (gdb) x/s 0x200db 0x200db: "A\021" ==== Verschiedene Ausgaben ==== (gdb) p/d 0xA # hex to dec $1 = 10 (gdb) p/t 0xA # hex to bin $2 = 1010 (gdb) p/t 0x4 # dec to bin $3 = 100 (gdb) p/x 10 # dec to hex $4 = 0xa ===== objdump ===== ==== objdump -d ==== objdump -d # oder -D ==== objdump -x ==== objdump -x ===== strace ===== ==== Details zu strace ==== strace ./002.elf execve("./002.elf", ["./002.elf"], 0xbe85f3a0 /* 44 vars */) = 0 write(1, "Enter a character: ", 19Enter a character: ) = 19 read(0, Benny "Benny\n", 8) = 6 write(1, "Benny\n", 6Benny ) = 6 exit(65) = ? +++ exited with 65 +++