Programas de ordenador (software) Jorge Juan Chico <[email protected]>, Julián Viejo Cortés <[email protected]> 2011, 2014, 2015 Departamento de Tecnología Electrónica Universidad de Sevilla Usted es libre de copiar, distribuir y comunicar públicamente la obra y de hacer obras derivadas siempre que se cite la fuente y se respeten las condiciones de la licencia Attribution-Share alike de Creative Commons. Puede consultar el texto completo de la licencia en http://creativecommons.org/licenses/by-sa/3.0/ Objetivos ● ● ● Conocer el tipo de instrucciones que ejecuta la CPU de un ordenador Comprender los procesos de compilación y ensamblado de los programas de ordenador Conocer la forma en que se organiza el software para crear programas complejos 2 Contenidos ● ● ● Lenguaje máquina y ensamblador Compiladores Jerarquía del software 3 Lenguaje máquina y ensamblador ● ● Lenguaje (código) máquina: código binario de las instrucciones que ejecuta la CPU Lenguaje ensamblador: representación del lenguaje máquina mediante palabras clave fáciles de entender para el programador Ensamblador mov mov mov mov mov mov top: top: add add add add dec dec jnz jnz done: done: mov mov eax, eax, 44 ebx, ebx, 00 ecx, ecx, xx ebx, ebx, [ecx] [ecx] ecx, ecx, 44 eax eax top top [sum], [sum], ebx ebx Código máquina 000000b0 000000b0 000000b5 000000b5 000000ba 000000ba 000000bf 000000bf 000000c2 000000c2 000000c5 000000c5 000000c7 000000c7 000000c9 000000c9 b804000000 b804000000 bb00000000 bb00000000 b9d0006000 b9d0006000 670319 670319 83c104 83c104 ffc8 ffc8 75f6 75f6 891c25e0006000 891c25e0006000 4 Lenguaje ensamblador Ejemplo ;; ejemplo ejemplo introductorio; introductorio; suma suma los los números números de de una una lista lista SECTION SECTION .data .data global global xx x: x: dd dd dd dd dd dd dd dd sum: sum: dd dd ;; comienzo comienzo del del segmento segmento de de datos datos 11 55 22 18 18 00 SECTION SECTION .text .text mov mov eax, eax, 44 mov mov ebx, ebx, 00 mov mov ecx, ecx, xx top: top: add add add add dec dec jnz jnz done: mov done: mov ebx, ebx, [ecx] [ecx] ecx, 4 ecx, 4 eax eax top top [sum], [sum], ebx ebx ;; comienzo comienzo del del segmento segmento de de código código ;; ;; ;; ;; ;; EAX EAX servirá servirá de de contador contador para para el el número de datos que quedan por número de datos que quedan por sumar sumar EBX almacenará la suma EBX almacenará la suma ECX ECX apunta apunta al al siguiente siguiente elemento elemento aa sumar sumar ;; ;; ;; ;; mueve mueve el el puntero puntero al al siguiente siguiente elemento elemento decrementa el contador decrementa el contador si si el el contador contador no no es es 0, 0, repetir repetir hecho, almacena el resultado hecho, almacena el resultado en en [sum] [sum] http://heather.cs.ucdavis.edu/~matloff/50/LinuxAssembly.html 5 Compiladores suma2.c #include #include <stdio.h> <stdio.h> int int main(void) main(void) {{ int int x[] x[] == {1, {1, 5, 5, 2, 2, 18}; 18}; int cont = 4; int cont = 4; int int sum sum == 0; 0; int i = 0; int i = 0; while while (cont (cont >> 0) 0) {{ sum sum == sum sum ++ x[i]; x[i]; i++; i++; cont--; cont--; }} printf("sum printf("sum == %d\n", %d\n", sum); sum); }} Compilador suma2.o 0: 0: 4: 4: 7: 7: a: a: b: b: d: d: e: e: 11: 11: 18: 18: 1f: 1f: 26: 26: 2d: 2d: 34: 34: 3b: 3b: 42: 42: 44: 44: 47: 47: 4b: 4b: 4e: 4e: 51: 51: 54: 54: 58: 58: 5a: 5a: 5d: 5d: 61: 61: 68: 68: 6d: 6d: 70: 70: 71: 71: 72: 72: 75: 75: 8d 8d 4c 4c 24 24 04 04 83 e4 f0 83 e4 f0 ff ff 71 71 fc fc 55 55 89 89 e5 e5 51 51 83 83 ec ec 34 34 c7 45 c7 45 e0 e0 01 01 00 00 00 00 00 00 c7 c7 45 45 e4 e4 05 05 00 00 00 00 00 00 c7 c7 45 45 e8 e8 02 02 00 00 00 00 00 00 c7 c7 45 45 ec ec 12 12 00 00 00 00 00 00 c7 c7 45 45 f0 f0 04 04 00 00 00 00 00 00 c7 c7 45 45 f4 f4 00 00 00 00 00 00 00 00 c7 c7 45 45 f8 f8 00 00 00 00 00 00 00 00 eb eb 10 10 8b 8b 45 45 f8 f8 8b 44 8b 44 85 85 e0 e0 01 45 f4 01 45 f4 ff ff 45 45 f8 f8 ff 4d ff 4d f0 f0 83 83 7d 7d f0 f0 00 00 7f ea 7f ea 8b 8b 45 45 f4 f4 89 44 89 44 24 24 04 04 c7 04 24 c7 04 24 00 00 00 00 00 00 00 00 e8 e8 fc fc ff ff ff ff ff ff 83 83 c4 c4 34 34 59 59 5d 5d 8d 8d 61 61 fc fc c3 c3 lea lea and and push push push push mov mov push push sub sub mov mov mov mov mov mov mov mov mov mov mov mov mov mov jmp jmp mov mov mov mov add add inc inc dec dec cmp cmp jg jg mov mov mov mov mov mov call call add add pop pop pop pop lea lea ret ret ecx,[esp+4] ecx,[esp+4] esp,0xfffffff0 esp,0xfffffff0 DWORD DWORD PTR PTR [ecx-4] [ecx-4] ebp ebp ebp,esp ebp,esp ecx ecx esp,0x34 esp,0x34 DWORD DWORD PTR PTR [ebp-32],0x1 [ebp-32],0x1 DWORD DWORD PTR PTR [ebp-28],0x5 [ebp-28],0x5 DWORD DWORD PTR PTR [ebp-24],0x2 [ebp-24],0x2 DWORD DWORD PTR PTR [ebp-20],0x12 [ebp-20],0x12 DWORD DWORD PTR PTR [ebp-16],0x4 [ebp-16],0x4 DWORD DWORD PTR PTR [ebp-12],0x0 [ebp-12],0x0 DWORD DWORD PTR PTR [ebp-8],0x0 [ebp-8],0x0 54 54 <main+0x54> <main+0x54> eax,DWORD eax,DWORD PTR PTR [ebp-8] [ebp-8] eax,DWORD PTR eax,DWORD PTR [ebp+eax*4-32] [ebp+eax*4-32] DWORD DWORD PTR PTR [ebp-12],eax [ebp-12],eax DWORD DWORD PTR PTR [ebp-8] [ebp-8] DWORD PTR DWORD PTR [ebp-16] [ebp-16] DWORD DWORD PTR PTR [ebp-16],0x0 [ebp-16],0x0 44 44 <main+0x44> <main+0x44> eax,DWORD eax,DWORD PTR PTR [ebp-12] [ebp-12] DWORD PTR [esp+4],eax DWORD PTR [esp+4],eax DWORD DWORD PTR PTR [esp],0x0 [esp],0x0 69 69 <main+0x69> <main+0x69> esp,0x34 esp,0x34 ecx ecx ebp ebp esp,[ecx-4] esp,[ecx-4] 9 Compiladores. Enlazado #include #include <stdio.h> <stdio.h> int int main(void) main(void) {{ int int x[] x[] == {1, {1, 5, 5, 2, 2, 18}; 18}; int cont = 4; int cont = 4; int int sum sum == 0; 0; int i int i == 0; 0; while while (cont (cont >> 0) 0) {{ sum sum == sum sum ++ x[i]; x[i]; i++; i++; cont--; cont--; }} printf("sum printf("sum == %d\n", %d\n", sum); sum); }} Compilador suma.o ● Interpretan un lenguaje de programación de alto nivel y generan código máquina que puede ejecutar la CPU biblioteca (printf, ...) Enlazador suma 10 Compilación. Comparativa mov mov eax, eax, 44 mov mov ebx, ebx, 00 mov ecx, mov ecx, xx top: top: add add ebx, ebx, [ecx] [ecx] add ecx, add ecx, 44 dec dec eax eax jnz jnz top top done: done: mov mov [sum], [sum], ebx ebx #include #include <stdio.h> <stdio.h> int int main(void) main(void) {{ int int x[] x[] == {1, {1, 5, 5, 2, 2, 18}; 18}; int cont = 4; int cont = 4; int int sum sum == 0; 0; int i = 0; int i = 0; while while (cont (cont >> 0) 0) {{ sum sum == sum sum ++ x[i]; x[i]; i++; i++; cont--; cont--; }} printf("sum printf("sum == %d\n", %d\n", sum); sum); }} 0: 0: 4: 4: 7: 7: a: a: b: b: d: d: e: e: 11: 11: 18: 18: 1f: 1f: 26: 26: 2d: 2d: 34: 34: 3b: 3b: 42: 42: 44: 44: 47: 47: 4b: 4b: 4e: 4e: 51: 51: 54: 54: 58: 58: 5a: 5a: 5d: 5d: 61: 61: 68: 68: 6d: 6d: 70: 70: 71: 71: 72: 72: 75: 75: 8d 8d 4c 4c 24 24 04 04 83 e4 f0 83 e4 f0 ff ff 71 71 fc fc 55 55 89 89 e5 e5 51 51 83 83 ec ec 34 34 c7 45 c7 45 e0 e0 01 01 00 00 00 00 00 00 c7 45 e4 05 00 00 c7 45 e4 05 00 00 00 00 c7 c7 45 45 e8 e8 02 02 00 00 00 00 00 00 c7 c7 45 45 ec ec 12 12 00 00 00 00 00 00 c7 c7 45 45 f0 f0 04 04 00 00 00 00 00 00 c7 c7 45 45 f4 f4 00 00 00 00 00 00 00 00 c7 c7 45 45 f8 f8 00 00 00 00 00 00 00 00 eb eb 10 10 8b 8b 45 45 f8 f8 8b 44 8b 44 85 85 e0 e0 01 45 f4 01 45 f4 ff ff 45 45 f8 f8 ff 4d ff 4d f0 f0 83 83 7d 7d f0 f0 00 00 7f ea 7f ea 8b 8b 45 45 f4 f4 89 44 89 44 24 24 04 04 c7 04 24 c7 04 24 00 00 00 00 00 00 00 00 e8 fc ff ff ff e8 fc ff ff ff 83 83 c4 c4 34 34 59 59 5d 5d 8d 8d 61 61 fc fc c3 c3 lea lea and and push push push push mov mov push push sub sub mov mov mov mov mov mov mov mov mov mov mov mov mov mov jmp jmp mov mov mov mov add add inc inc dec dec cmp cmp jg jg mov mov mov mov mov mov call call add add pop pop pop pop lea lea ret ret ecx,[esp+4] ecx,[esp+4] esp,0xfffffff0 esp,0xfffffff0 DWORD DWORD PTR PTR [ecx-4] [ecx-4] ebp ebp ebp,esp ebp,esp ecx ecx esp,0x34 esp,0x34 DWORD DWORD PTR PTR [ebp-32],0x1 [ebp-32],0x1 DWORD PTR DWORD PTR [ebp-28],0x5 [ebp-28],0x5 DWORD DWORD PTR PTR [ebp-24],0x2 [ebp-24],0x2 DWORD DWORD PTR PTR [ebp-20],0x12 [ebp-20],0x12 DWORD DWORD PTR PTR [ebp-16],0x4 [ebp-16],0x4 DWORD DWORD PTR PTR [ebp-12],0x0 [ebp-12],0x0 DWORD DWORD PTR PTR [ebp-8],0x0 [ebp-8],0x0 54 54 <main+0x54> <main+0x54> eax,DWORD eax,DWORD PTR PTR [ebp-8] [ebp-8] eax,DWORD PTR eax,DWORD PTR [ebp+eax*4-32] [ebp+eax*4-32] DWORD DWORD PTR PTR [ebp-12],eax [ebp-12],eax DWORD DWORD PTR PTR [ebp-8] [ebp-8] DWORD PTR DWORD PTR [ebp-16] [ebp-16] DWORD DWORD PTR PTR [ebp-16],0x0 [ebp-16],0x0 44 44 <main+0x44> <main+0x44> eax,DWORD eax,DWORD PTR PTR [ebp-12] [ebp-12] DWORD PTR [esp+4],eax DWORD PTR [esp+4],eax DWORD DWORD PTR PTR [esp],0x0 [esp],0x0 69 <main+0x69> 69 <main+0x69> esp,0x34 esp,0x34 ecx ecx ebp ebp esp,[ecx-4] esp,[ecx-4] 11 Jerarquía del software Sin S.O. (stand-alone) Con S.O. App1 App1 App2 App2 App3 App3 Aplicación Aplicación (programa) (programa) Sistema Sistema Operativo Operativo Hardware Hardware Hardware Hardware 12 Jerarquía del software aplicaciones utilidades bibliotecas kernel S.O. hardware 13