Técnicas Digitales III

Anuncio
Procesadores de 32 bits
Integración de C y Assembler
Formas de realizar llamadas
 Uso
de Call y Ret
 Uso de Enter y Leave en conjunto con Call
y Ret
Preparación del stack
 Establecer
un segmento para stack.
 Cargar el selecto de segmento en SS
usando las instrucciones MOV, POP, o LSS.
 Cargar el puntero al stack en ESP usando
MOV, POP, o LSS. La instrucción LSS
puede utilizarse para cargar SS y ESP en
una sóla operación.
 Considerar la alineación del stack.
Funciones en Assembler invocadas desde C
 Se
utilizan a las instrucciones Enter y
Leave.
 Estas adecuan el stack para la ejecución
de la retina en assembler.
 El resultado de la función se obtiene en
EAX
Ejemplo: Suma.c
extern int suma_asm(int a, int b);
#include <unistd.h>
#include <stdio.h>
int main (void) {
int r=0;
int s=4;
int t=5;
printf("Calculando...\n");
r=suma_asm(s,t);
printf("El resultado es: %d\n",r);
return(0)
}
extern int suma_asm(int a, int b);
 La
sentencia extern le indica al
compilador que la llamada a la función
suma_asm se obtendrá de otro código
objeto.
 La función devolverá una entero, EAX.
 La función necesita dos enteros como
argumentos, estos de almacenarán en la
pila.
suma_asm.asm
Hace la conexión con extern
GLOBAL suma_asm
%define sumando1
ebp+8
%define sumando2
ebp+12
suma_asm:
Etiqueta que marca el comienzo
enter 8,0
mov eax,[sumando1]
Adecua el stack, ebp y
mov ebx,[sumando2]
reserva dos dobles words
Para uso interno de la rutina
add eax,ebx
leave
Restablece el stack y ebp,
ret
a partir del valor de ebp
Instrucción ENTER n,0
 Push
EBP
 EBP ← ESP
 ESP ← ESP - n
Instrucción LEAVE
 ESP
← EBP
 Pop EBP
Compilado de C y Assembler
 Assembler:

nasm -f elf suma_asm.asm -l suma_asm.lst
 C:
 gcc
-c suma.c
 Ambos
generan código objeto, que se
conjuga con:
 gcc
-g suma.o suma_asm.o -o suma
El archivo Makefile
$ cat Makefile
suma: suma.obj suma_asm.obj
gcc -ggdb suma.o suma_asm.o -o suma
suma.obj: suma.c
gcc -ggdb -c suma.c
suma_asm.obj: suma_asm.asm
nasm -f elf -g suma_asm.asm -l suma_asm.lst
Invocando al Makefile
 Se
lo invoca con el comando make y una
etiqueta.
 En ausencia de etiqueta tomará la
primera que encuentra en el Makefile, en
nuestro caso suma:
 Luego de la etiqueta van los requisitos
para ejecutar la etiqueta
 En
el caso de suma: requiere de las etiquetas
suma.obj y suma_asm.obj
Sintaxis de Makefile
A
su vez la etiqueta suma.obj requiere del
archivo suma.c
 Si
lo tiene ejecuta lo que está debajo de la
etiqueta, estas líneas deben comenzar con
tabulador, en este caso gcc -ggdb -c suma.c
 La opción -c de gcc genera sólo código objeto
de nombre suma.o
 La opción -ggdb generación información para
el gdb
Sintaxis de Makefile
A
su vez la etiqueta suma_asm.obj
requiere del archivo suma_asm.asm
Si lo tiene ejecuta lo que está debajo de la
etiqueta, estas líneas deben comenzar con
tabulador, en este caso:
nasm -f elf -g suma_asm.asm -l suma_asm.lst
 La opción -f de nasm genera sólo código objeto
de nombre suma_asm.obj en formato elf
 La opción -g genera información para el gdb

Sintaxis de Makefile
 Ahora
que la etiqueta suma: tiene sus
requisitos, se ejecutará:
 gcc
-ggdb suma.o suma_asm.o -o suma
Vincula ambos objetos manteniendo la
información para el gdb
Ejecutando make
$ make
gcc -c suma.c
nasm -f elf suma_asm.asm -l suma_asm.lst
gcc -g suma.o suma_asm.o -o suma
(gdb) disas main

0x080483f4 <main+0>:
push %ebp

0x080483f5 <main+1>:
mov
%esp,%ebp

0x080483f7 <main+3>:
and
$0xfffffff0,%esp

0x080483fa <main+6>:
sub
$0x20,%esp
Salva ebp, lo alinea con esp con esto queda
listo para la instrucción LEAVE
Alinea esp a 16
Deja espacio para variables locales y
parámetros
(gdb) disas main (2)

0x080483fd <main+9>:

0x08048405 <main+17>: movl $0x14,0x18(%esp)

0x0804840d <main+25>: movl $0xb,0x1c(%esp)
int r=0;
int s=20;
int t=11;
movl $0x0,0x14(%esp)
(gdb) disas main (3)

0x08048415 <main+33>: movl $0x8048530,(%esp)

0x0804841c <main+40>: call 0x8048330
<puts@plt>
printf("Calculando...\n");
(gdb) disas main (4)

0x08048421 <main+45>: mov
0x1c(%esp),%eax

0x08048425 <main+49>: mov
%eax,0x4(%esp)

0x08048429 <main+53>: mov
0x18(%esp),%eax

0x0804842d <main+57>: mov
%eax,(%esp)

0x08048430 <main+60>: call 0x8048460 <suma_asm>

0x08048435 <main+65>: mov
r=suma_asm(s,t);
%eax,0x14(%esp)
(gdb) disas main (5)

0x08048439 <main+69>: mov
$0x804853e,%eax

0x0804843e <main+74>: mov
0x14(%esp),%edx

0x08048442 <main+78>: mov
%edx,0x4(%esp)

0x08048446 <main+82>: mov
%eax,(%esp)

0x08048449 <main+85>: call 0x8048320 <printf@plt>
printf("El resultado es: %d\n",r);
(gdb) disas main (6)

0x0804844e <main+90>: mov

0x08048453 <main+95>: leave

0x08048454 <main+96>: ret
return(0)
$0x0,%eax
Referencias
 Intel®
64 and IA-32 Architectures
Software Developer’s Manual Volume 1:
Basic Architecture, Capítulo 6
 http://www.nasm.us/doc/
 http://gcc.gnu.org/onlinedocs/
 Paquetes recomendados:
 gcc
gcc-doc nasm make make-doc gdb ddd
Descargar