En esta entrada se parte de unos conocimientos de programación básicos de ARM y C.
gcc
gcc (GNU Compiler Collection) es una colección de compiladores libres y a continuación se presentan sus principales argumentos:
- -c Es utilizado para compilar o ensamblar los ficheros fuentes, pero sin enlazar.
- -S Sirve para transformar un archivo que contiene un programa fuente en C en un archivo fuente en ensamblador.
- -o archivo La salida del compilador se almacena en el archivo indicado.
- -g Sirve para generar información de depuración, muy útil para poder utilizar posteriormente en programas de depuración.
- -l librería Añade la libreria especificada en la compilación.
Para probar algunas opciones se va a partir del programa holamundo
#include<stdio.h>
main(){
printf("Hola Mundo\n");
}
main(){
printf("Hola Mundo\n");
}
Se va a compilar y ejecutar para ello
gcc -o holamundo holamundo.c
chmod +x holamundo
./holamundo
chmod +x holamundo
./holamundo
Si se desea generar el código en ensamblador
gcc -S holamundo.c
as
as (GNU Assembler) es un ensamblador del proyecto GNU, se van a citar aquellas que han sido más utilizadas.
- -o archivo Sirve para que el archivo objeto generado se denomine archivo.
- -g Sirve para generar información de depuración, muy útil para poder utilizar posteriormente en programas de depuración.
as –o holamundo.o holamundo.s
ld
ld (GNU Linker) sirve para enlazar ficheros objeto y generar un ejecutable.
- -l librería Añade la librería especificada en la compilación.
- -m maquina Especifica la arquitectura a emplear cuando se desensamblen ficheros objeto.
- -dynamic-linker Establece el enlazado dinámico
- -T Permite definir donde comienzan las secciones
- -o archivo Sirve para que el archivo objeto generado se denomine archivo.
ld -dynamic-linker /lib/ld-linux.so.3 -o p1a p1a.o copy.o -T ldscript.ld
objdump
Es una herramienta que forma parte de las GNU Binutils, es una herramienta que muestra información sobre los programas objeto.
Se proceden a mostrar las entradas que se han considerado más relevantes del manual
- -d /--disassemble Muestra los mnemónicos de ensamblador para las instrucciones máquina de fichobj. Esta opción sólo desensambla aquellas secciones para las que se espera que contengan instrucciones.
- -D / --disassemble-all Como -d, pero desensambla los contenidos de todas las secciones, no sólo aquéllas donde se espera que contengan instrucciones.
- ‐j / ‐‐section= nombre Seleccionar información sólo de la sección mencionada.
- -S Intercala código fuente con desensamblado.
- ‐s / ‐‐full‐contents Mostrar contenidos completos de todas las secciones.
- -t Muestra las entradas de la tabla de símbolos.
Como ejemplo se va a partir del programa holamundo.c definido anteriormente, a continuación se procederá a compilar el archivo con las opciones –g para que genere información de depuración y –o para indicar un fichero de salida.
gcc –g –o holamundo holamundo.c
A modo de ejemplo se va a proceder a utilizar la opción –S (desensambla e intercala código fuente)
objdump –S holamundo
holamundo: file format elf32-littlearm
Disassembly of section .init:
000082cc <_init>:
82cc: e92d4008 push {r3, lr}
82d0: eb000020 bl 8358
82d4: e8bd8008 pop {r3, pc}
Disassembly of section .plt:
000082d8 <.plt>:
82d8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
82dc: e59fe004 ldr lr, [pc, #4] ; 82e8 <_init data-blogger-escaped-x1c="">
82e0: e08fe00e add lr, pc, lr
82e4: e5bef008 ldr pc, [lr, #8]!
82e8: 00008280 .word 0x00008280
82ec: e28fc600 add ip, pc, #0
82f0: e28cca08 add ip, ip, #32768 ; 0x8000
82f4: e5bcf280 ldr pc, [ip, #640]! ; 0x280
82f8: e28fc600 add ip, pc, #0
82fc: e28cca08 add ip, ip, #32768 ; 0x8000
8300: e5bcf278 ldr pc, [ip, #632]! ; 0x278
8304: e28fc600 add ip, pc, #0
8308: e28cca08 add ip, ip, #32768 ; 0x8000
830c: e5bcf270 ldr pc, [ip, #624]! ; 0x270
8310: e28fc600 add ip, pc, #0
8314: e28cca08 add ip, ip, #32768 ; 0x8000
8318: e5bcf268 ldr pc, [ip, #616]! ; 0x268
Disassembly of section .text:
0000831c <_start>:
831c: e3a0b000 mov fp, #0
8320: e3a0e000 mov lr, #0
8324: e49d1004 pop {r1} ; (ldr r1, [sp], #4)
8328: e1a0200d mov r2, sp
832c: e52d2004 push {r2} ; (str r2, [sp, #-4]!)
8330: e52d0004 push {r0} ; (str r0, [sp, #-4]!)
8334: e59fc010 ldr ip, [pc, #16] ; 834c <_start data-blogger-escaped-x30="">
8338: e52dc004 push {ip} ; (str ip, [sp, #-4]!)
833c: e59f000c ldr r0, [pc, #12] ; 8350 <_start data-blogger-escaped-x34="">
8340: e59f300c ldr r3, [pc, #12] ; 8354 <_start data-blogger-escaped-x38="">
8344: ebffffeb bl 82f8 <_init data-blogger-escaped-x2c="">
8348: ebfffff0 bl 8310 <_init data-blogger-escaped-x44="">
834c: 00008444 .word 0x00008444
8350: 000083c8 .word 0x000083c8
8354: 000083e4 .word 0x000083e4
00008358 :
8358: e59f3014 ldr r3, [pc, #20] ; 8374
835c: e59f2014 ldr r2, [pc, #20] ; 8378
8360: e08f3003 add r3, pc, r3
8364: e7933002 ldr r3, [r3, r2]
8368: e3530000 cmp r3, #0
836c: 012fff1e bxeq lr
8370: eaffffe3 b 8304 <_init data-blogger-escaped-x38="">
8374: 00008200 .word 0x00008200
8378: 0000001c .word 0x0000001c
0000837c <__do_global_dtors_aux>:
837c: e59f3010 ldr r3, [pc, #16] ; 8394 <__do_global_dtors_aux data-blogger-escaped-x18="">
8380: e5d32000 ldrb r2, [r3]
8384: e3520000 cmp r2, #0
8388: 03a02001 moveq r2, #1
838c: 05c32000 strbeq r2, [r3]
8390: e12fff1e bx lr
8394: 00010590 .word 0x00010590
00008398 :
8398: e59f0020 ldr r0, [pc, #32] ; 83c0
839c: e92d4008 push {r3, lr}
83a0: e5903000 ldr r3, [r0]
83a4: e3530000 cmp r3, #0
83a8: 08bd8008 popeq {r3, pc}
83ac: e59f3010 ldr r3, [pc, #16] ; 83c4
83b0: e3530000 cmp r3, #0
83b4: 08bd8008 popeq {r3, pc}
83b8: e12fff33 blx r3
83bc: e8bd8008 pop {r3, pc}
83c0: 00010474 .word 0x00010474
83c4: 00000000 .word 0x00000000
000083c8 :
#include
main(){
83c8: e92d4800 push {fp, lr}
83cc: e28db004 add fp, sp, #4
printf("Hola Mundo\n");
83d0: e59f0008 ldr r0, [pc, #8] ; 83e0
83d4: ebffffc4 bl 82ec <_init data-blogger-escaped-x20="">
}
83d8: e1a00003 mov r0, r3
83dc: e8bd8800 pop {fp, pc}
83e0: 00008454 .word 0x00008454
000083e4 <__libc_csu_init>:
83e4: e92d45f8 push {r3, r4, r5, r6, r7, r8, sl, lr}
83e8: e1a06000 mov r6, r0
83ec: e59f5048 ldr r5, [pc, #72] ; 843c <__libc_csu_init data-blogger-escaped-x58="">
83f0: e59fa048 ldr sl, [pc, #72] ; 8440 <__libc_csu_init data-blogger-escaped-x5c="">
83f4: e08f5005 add r5, pc, r5
83f8: e08fa00a add sl, pc, sl
83fc: e065a00a rsb sl, r5, sl
8400: e1a07001 mov r7, r1
8404: e1a08002 mov r8, r2
8408: ebffffaf bl 82cc <_init>
840c: e1b0a14a asrs sl, sl, #2
8410: 08bd85f8 popeq {r3, r4, r5, r6, r7, r8, sl, pc}
8414: e3a04000 mov r4, #0
8418: e4953004 ldr r3, [r5], #4
841c: e1a00006 mov r0, r6
8420: e1a01007 mov r1, r7
8424: e1a02008 mov r2, r8
8428: e2844001 add r4, r4, #1
842c: e12fff33 blx r3
8430: e154000a cmp r4, sl
8434: 1afffff7 bne 8418 <__libc_csu_init data-blogger-escaped-x34="">
8438: e8bd85f8 pop {r3, r4, r5, r6, r7, r8, sl, pc}
843c: 00008070 .word 0x00008070
8440: 00008070 .word 0x00008070
00008444 <__libc_csu_fini>:
8444: e12fff1e bx lr
Disassembly of section .fini:
00008448 <_fini>:
8448: e92d4008 push {r3, lr}
844c: e8bd8008 pop {r3, pc}
000082cc <_init>:
82cc: e92d4008 push {r3, lr}
82d0: eb000020 bl 8358
82d4: e8bd8008 pop {r3, pc}
Disassembly of section .plt:
000082d8 <.plt>:
82d8: e52de004 push {lr} ; (str lr, [sp, #-4]!)
82dc: e59fe004 ldr lr, [pc, #4] ; 82e8 <_init data-blogger-escaped-x1c="">
82e0: e08fe00e add lr, pc, lr
82e4: e5bef008 ldr pc, [lr, #8]!
82e8: 00008280 .word 0x00008280
82ec: e28fc600 add ip, pc, #0
82f0: e28cca08 add ip, ip, #32768 ; 0x8000
82f4: e5bcf280 ldr pc, [ip, #640]! ; 0x280
82f8: e28fc600 add ip, pc, #0
82fc: e28cca08 add ip, ip, #32768 ; 0x8000
8300: e5bcf278 ldr pc, [ip, #632]! ; 0x278
8304: e28fc600 add ip, pc, #0
8308: e28cca08 add ip, ip, #32768 ; 0x8000
830c: e5bcf270 ldr pc, [ip, #624]! ; 0x270
8310: e28fc600 add ip, pc, #0
8314: e28cca08 add ip, ip, #32768 ; 0x8000
8318: e5bcf268 ldr pc, [ip, #616]! ; 0x268
Disassembly of section .text:
0000831c <_start>:
831c: e3a0b000 mov fp, #0
8320: e3a0e000 mov lr, #0
8324: e49d1004 pop {r1} ; (ldr r1, [sp], #4)
8328: e1a0200d mov r2, sp
832c: e52d2004 push {r2} ; (str r2, [sp, #-4]!)
8330: e52d0004 push {r0} ; (str r0, [sp, #-4]!)
8334: e59fc010 ldr ip, [pc, #16] ; 834c <_start data-blogger-escaped-x30="">
8338: e52dc004 push {ip} ; (str ip, [sp, #-4]!)
833c: e59f000c ldr r0, [pc, #12] ; 8350 <_start data-blogger-escaped-x34="">
8340: e59f300c ldr r3, [pc, #12] ; 8354 <_start data-blogger-escaped-x38="">
8344: ebffffeb bl 82f8 <_init data-blogger-escaped-x2c="">
8348: ebfffff0 bl 8310 <_init data-blogger-escaped-x44="">
834c: 00008444 .word 0x00008444
8350: 000083c8 .word 0x000083c8
8354: 000083e4 .word 0x000083e4
00008358 :
8358: e59f3014 ldr r3, [pc, #20] ; 8374
835c: e59f2014 ldr r2, [pc, #20] ; 8378
8360: e08f3003 add r3, pc, r3
8364: e7933002 ldr r3, [r3, r2]
8368: e3530000 cmp r3, #0
836c: 012fff1e bxeq lr
8370: eaffffe3 b 8304 <_init data-blogger-escaped-x38="">
8374: 00008200 .word 0x00008200
8378: 0000001c .word 0x0000001c
0000837c <__do_global_dtors_aux>:
837c: e59f3010 ldr r3, [pc, #16] ; 8394 <__do_global_dtors_aux data-blogger-escaped-x18="">
8380: e5d32000 ldrb r2, [r3]
8384: e3520000 cmp r2, #0
8388: 03a02001 moveq r2, #1
838c: 05c32000 strbeq r2, [r3]
8390: e12fff1e bx lr
8394: 00010590 .word 0x00010590
00008398 :
8398: e59f0020 ldr r0, [pc, #32] ; 83c0
839c: e92d4008 push {r3, lr}
83a0: e5903000 ldr r3, [r0]
83a4: e3530000 cmp r3, #0
83a8: 08bd8008 popeq {r3, pc}
83ac: e59f3010 ldr r3, [pc, #16] ; 83c4
83b0: e3530000 cmp r3, #0
83b4: 08bd8008 popeq {r3, pc}
83b8: e12fff33 blx r3
83bc: e8bd8008 pop {r3, pc}
83c0: 00010474 .word 0x00010474
83c4: 00000000 .word 0x00000000
000083c8 :
#include
main(){
83c8: e92d4800 push {fp, lr}
83cc: e28db004 add fp, sp, #4
printf("Hola Mundo\n");
83d0: e59f0008 ldr r0, [pc, #8] ; 83e0
83d4: ebffffc4 bl 82ec <_init data-blogger-escaped-x20="">
}
83d8: e1a00003 mov r0, r3
83dc: e8bd8800 pop {fp, pc}
83e0: 00008454 .word 0x00008454
000083e4 <__libc_csu_init>:
83e4: e92d45f8 push {r3, r4, r5, r6, r7, r8, sl, lr}
83e8: e1a06000 mov r6, r0
83ec: e59f5048 ldr r5, [pc, #72] ; 843c <__libc_csu_init data-blogger-escaped-x58="">
83f0: e59fa048 ldr sl, [pc, #72] ; 8440 <__libc_csu_init data-blogger-escaped-x5c="">
83f4: e08f5005 add r5, pc, r5
83f8: e08fa00a add sl, pc, sl
83fc: e065a00a rsb sl, r5, sl
8400: e1a07001 mov r7, r1
8404: e1a08002 mov r8, r2
8408: ebffffaf bl 82cc <_init>
840c: e1b0a14a asrs sl, sl, #2
8410: 08bd85f8 popeq {r3, r4, r5, r6, r7, r8, sl, pc}
8414: e3a04000 mov r4, #0
8418: e4953004 ldr r3, [r5], #4
841c: e1a00006 mov r0, r6
8420: e1a01007 mov r1, r7
8424: e1a02008 mov r2, r8
8428: e2844001 add r4, r4, #1
842c: e12fff33 blx r3
8430: e154000a cmp r4, sl
8434: 1afffff7 bne 8418 <__libc_csu_init data-blogger-escaped-x34="">
8438: e8bd85f8 pop {r3, r4, r5, r6, r7, r8, sl, pc}
843c: 00008070 .word 0x00008070
8440: 00008070 .word 0x00008070
00008444 <__libc_csu_fini>:
8444: e12fff1e bx lr
Disassembly of section .fini:
00008448 <_fini>:
8448: e92d4008 push {r3, lr}
844c: e8bd8008 pop {r3, pc}
Muestra los símbolos con los que enlaza un programa.
nm holamundo
00010478 d _DYNAMIC
00010568 d _GLOBAL_OFFSET_TABLE_
00008450 R _IO_stdin_used
w _Jv_RegisterClasses
00008468 r __FRAME_END__
00010474 d __JCR_END__
00010474 d __JCR_LIST__
00010594 A __bss_end__
00010590 A __bss_start
00010590 A __bss_start__
00010588 D __data_start
0000837c t __do_global_dtors_aux
00010470 t __do_global_dtors_aux_fini_array_entry
0001058c D __dso_handle
00010594 A __end__
0001046c t __frame_dummy_init_array_entry
w __gmon_start__
00010470 t __init_array_end
0001046c t __init_array_start
00008444 T __libc_csu_fini
000083e4 T __libc_csu_init
U __libc_start_main@@GLIBC_2.4
00010594 A _bss_end__
00010590 A _edata
00010594 A _end
00008448 T _fini
000082cc T _init
0000831c T _start
U abort@@GLIBC_2.4
00008358 t call_gmon_start
00010590 b completed.5637
00010588 W data_start
00008398 t frame_dummy
000083c8 T main
U puts@@GLIBC_2.4
00010568 d _GLOBAL_OFFSET_TABLE_
00008450 R _IO_stdin_used
w _Jv_RegisterClasses
00008468 r __FRAME_END__
00010474 d __JCR_END__
00010474 d __JCR_LIST__
00010594 A __bss_end__
00010590 A __bss_start
00010590 A __bss_start__
00010588 D __data_start
0000837c t __do_global_dtors_aux
00010470 t __do_global_dtors_aux_fini_array_entry
0001058c D __dso_handle
00010594 A __end__
0001046c t __frame_dummy_init_array_entry
w __gmon_start__
00010470 t __init_array_end
0001046c t __init_array_start
00008444 T __libc_csu_fini
000083e4 T __libc_csu_init
U __libc_start_main@@GLIBC_2.4
00010594 A _bss_end__
00010590 A _edata
00010594 A _end
00008448 T _fini
000082cc T _init
0000831c T _start
U abort@@GLIBC_2.4
00008358 t call_gmon_start
00010590 b completed.5637
00010588 W data_start
00008398 t frame_dummy
000083c8 T main
U puts@@GLIBC_2.4
C y ARM
A continuación se va a mostrar el siguiente ejemplo, la función en ensamblador es una suma almacenada en suma.s y es llamada desde el programa main.c.
main.c
#include<stdio.h>
extern int suma(int a, int b);
int main(int argc, char *argv[])
{
printf("== sum ==\n");
int a = 71;
int b = 29;
printf("%d + %d = %d\n", a, b, suma(a, b));
return 0;
}
extern int suma(int a, int b);
int main(int argc, char *argv[])
{
printf("== sum ==\n");
int a = 71;
int b = 29;
printf("%d + %d = %d\n", a, b, suma(a, b));
return 0;
}
suma.s
.align 2
.arm
.global suma
suma:
add r2, r0, r1 in r2
mov r0, r2
mov pc, lr
.arm
.global suma
suma:
add r2, r0, r1 in r2
mov r0, r2
mov pc, lr
Pasos para tener este programa como ejecutable
gcc -c main.c
as -o suma.o suma.s
gcc -o main suma.o main.o
chmod a+x suma
./suma
as -o suma.o suma.s
gcc -o main suma.o main.o
chmod a+x suma
./suma
ARM y C
En el siguiente ejemplo partimos de un fichero copy.c que copia de una cadena origen a una cadena destino n carácteres.
void __c_copy(char *orig, char *dest, int tam) {
int i;
for(i=0;i<tam;i++){
dest[i]=orig[i];
}
}
int i;
for(i=0;i<tam;i++){
dest[i]=orig[i];
}
}
El siguiente programa en ensamblador contenido en el fichero main.s emplea la función anterior para copiar una cadena y mostrarla por pantalla.
.text
.global _start
_start:
.extern __c_copy
ldr r0, =.orig
ldr r1, =.dest
mov r2, #11
bl __c_copy
ldr r0, =.dest
bl _imprime
bl exit
.global _imprime
_imprime:
stmdb sp!, {r0,r1,lr}
mov r1,r0
ldr r0, =.string
bl printf
ldmia sp!, {r0,r1,pc}
.data
.string:
.asciz "%s\n"
.orig:
.asciz "Hola Mundo"
.dest:
.space 11
.end
.global _start
_start:
.extern __c_copy
ldr r0, =.orig
ldr r1, =.dest
mov r2, #11
bl __c_copy
ldr r0, =.dest
bl _imprime
bl exit
.global _imprime
_imprime:
stmdb sp!, {r0,r1,lr}
mov r1,r0
ldr r0, =.string
bl printf
ldmia sp!, {r0,r1,pc}
.data
.string:
.asciz "%s\n"
.orig:
.asciz "Hola Mundo"
.dest:
.space 11
.end
Pasos para tener este programa como ejecutable
gcc -c copy.c
as -o main.o main.s
ld -dynamic-linker /lib/ld-linux.so.3 -lc -o main main.o copy.o
chmod a+x main
./main
as -o main.o main.s
ld -dynamic-linker /lib/ld-linux.so.3 -lc -o main main.o copy.o
chmod a+x main
./main
No hay comentarios:
Publicar un comentario