Ensamblaje, etc - Organización del Computador II

Transcripción

Ensamblaje, etc - Organización del Computador II
Ensamblaje, etc
Patricia Borensztejn
Organización del Computador 2
Segundo 2016
Programa Almacenado
•
•
•
•
•
La primera computadora digital de propósito
general fue la compuadora ENIAC, construida
en la Universidad de Pensilvania, Escuela de
Ingeniería Eléctrica, USA. Contrato secreto
firmado en 1943 entre la Escuela y el Ejército
de EEUU.
Sus diseñadores fueron John Mauchly y J.
Presper Eckert, de dicha universidad.
Era de propósito general porque era
«programable», sin embargo, el programa
que contenía las instrucciones no se
almacenaba en memoria, sino que se
introducía a mano, conectando y
desconectando cables a las clavijas. Esta
tarea, la realizaban las mujeres que
programaron el ENIAC.
Los datos si eran almacenados en tubos de
vacío: solo podían almacenarse 20 números
de 10 dígitos cada uno
https://www.dc.uba.ar/Members/patricia/His
torias%20
Programa Almacenado
• Los diseñadores Mauchly y Eckert comprendieron que era necesario que
las instrucciones estuvieran almacenadas pues la programación manual
podía tardar varias semanas. (No había instrucciones para guardar el
programa, no había unidad de control que las identificara..)
• Pero la cuestión era justamente tecnológica: había que encontrar una
tecnología idónea para la memoria de instrucciones. Solo había tubos de
vacío!
• En USA y GB suceden al mismo tiempo (1946) las siguientes dos cosas:
– En Usa, Eckert inventa los líneas de retardo de mercurio, que sirven para
implementar memoria. Y con ella diseñan EDVAC, el primer computador de
programa almacenado
– En GB, Turing diseña la ASE (Automatic Computing Engine) en el National
Physical Laboratory. ASE era una computadora digital de proposito general y
programa almacenado. Su primer prototipo fue conocido como The Baby y
fue construido en la Universidad de Manchester por Williams, Kilburn y Tootill.
Williams había inventado otra manera de contruir memorias basado en los
rayos catódicos.
• Sabia Usted que ….The Baby fue nada mas y nada menos que el ancestro
de la Clementina, la que trajo Sadosky a la Argentina. Ferranti fue la
empresa que comercializó el diseño de esta familia de computadoras
Programa Almacenado
• Por esas cosas de la vida,
aunque fueron Mauchly y
Eckert los que
construyeron EDVAC , el
que escribió el informe fue
John von Neumann.
• Ese informe dio origen a
lo que hoy conocemos
como arquitectura von
Neumann
Arquitectura llamada «Von Neumann»
Arquitectura von Neumann
• Caracterizada por:
– Una Memoria donde se alojan tanto Datos como
Instrucciones
– Una Unidad de Control que las importa, decodifica
e imparte las órdenes para su ejecución
– Una Unidad de Proceso responsable de la
ejecución
– Una Unidad de Entrada / Salida conecta al exterior
Entonces, los programas …
• Deben estar en memoria para poder ser ejecutados
• ¿Cómo se cargan en memoria?
– Hay que copiarlos del disco o desde donde estén a la
memoria principal
• ¿Quién lo hace?
– El sistema operativo, bajo demanda de alguien, que
podemos ser, entre otros, nosotros
• ¿Qué se carga en memoria?
– Las instrucciones en lenguaje máquina del programa que
el procesador va a ejecutar
• ¿Cómo se generan las instrucciones en lenguaje
máquina?
Tipos de Archivos: .asm 16 bits en DOS
nasm –l simdos.lst simdos.asm
1
org 100h
2
3
section .text
4
;Aquí va el código
5
;Cuando se hace int 21h se llama al sistema operativo, que ejecuta la función que indique AH
6
;AH=9 imprime la cadena apuntada por DS:DX, terminada en "$"
7
;AH=4Ch termina el programa, con código de salida AL
8
9 00000000 BA[0000]
mov dx,cadena
10 00000003 B409
mov ah,9
11 00000005 CD21
int 21h
12
13 00000007 B8004C
mov ax,0x4C00
14 0000000A CD21
int 21h
15
16
section .data
17
;Aqui los datos inicializados
18
;los caracteres 10 y 13 significan retorno de línea en MS-DOS.
19 00000000 5175E920706173612Ccadena DB "Qué pasa, mundo",13,10,"$"
19 00000009 206D756E646F0D0A24
20
21
section .bss
22
;Y aqui los datos no inicializados, si los hubiera
nasm –l simdos.asm
• Hay dos secciones y las dos comienzan en la
dirección 0
• Sección Código: todo en hexadecimal
dirección
Instrucción en LM
00000000
00000003
00000005
00000007
0000000 A
BA[0000]
B409
CD21
B8004C
CD21
Instrucción en LE
mov dx,cadena
mov ah,9
int 21h
mov ax,0x4C00
int 21h
Formato de Instrucción
Formato de Instrucción
• Instrucción MOV DX, offset16
– Codificada asi: B8+rw: B8 + 010= BA
– DX se codifica como 010 ( w=1, bit 3)
– Offset: pone 0000 pues las direcciones son
relativas a cero, cadena esta en la dirección cero
del segmento de datos.
B8+ rw
MOV r16,imm16
Move imm16 to r16.
Formato de Instrucción
• Instrucción MOV ah, 9
– Codificada asi: B0+rb: B0 + 0100= B4
– Offset: pone 09 pues es un inmediato de 8 bits
– Registro AH se codifica con 100 y w=0 (bit3)
B0+ rb
MOV r8,imm8
Move imm8 to r8.
Formato de Instrucción
• INT 21: CD 21
Formato de Instrucción
• Instrucción MOV AX, 0x4C00
– Codificada asi: B8+rw: B8 + 1000= B8
– Offset: pone 4C00 pues es un inmediato de 16 bits
– Registro AX se codifica con 000 y w=1 (bit3)
B8+ rw
MOV r16,imm16
Move imm16 to r16.
Datos
• La sección de datos contiene la cadena :
"Qué pasa, mundo",13,10,"$ y la vemos de esta
manera:
51 75 E9 20 70 61 73 61 2C
20 6D 75 6E 64 6F 0D 0A 24
Donde:
20 es el carácter ASCII espacio
2C es la coma
etc
Nasm simdos.asm –o sim2.com
• Ese comando crea un ejecutable: sim2.com
Lo miramos usando un editor hexa
Direcciones Absolutas
• Todo coincide con el archivo lst menos …
• La dirección del string cadena que ha sido reemplazado
por la dirección 0c 01. (010c)
• Esto es porque el binario comienza en la dirección
0100. Ese es el motivo de la directiva org 100.
Ejecutables .COM
• El cargador de DOS
ubica la imagen exacta
del binario a partir de
la dirección 0100
(hexa)
• Desde la dirección
0000 a la 00FF hay una
estructura de datos
que construye el SO y
que se llamaba PSP.
Entre otros
parámetros, esta la
línea de comando con
sus parámetros del
ejecutable.
• El siguiente código
muestra los
parámetros de la
línea de comando:
org 100h
; INT 21h subfunction 9 requires '$' to terminate string
xor bx, bx
mov bl, [80h]
cmp bl, 126
ja exit
mov byte [bx + 81h], '$'
; print the string
mov ah, 9
mov dx, 81h
int 21h
exit:
mov ax, 4C00h
int 21h
Archivo ejecutable
• Nasm ha generado un ejecutable, pero si lo
intento ejecutar en la ventana de comando no
me lo permite
Archivos .COM
• Es un archivo ejecutable, que solo puede ser
ejecutado en un emulador de DOS, el antiguo
sistema operativo de 16 bits.
• En esa época, los segmentos eran máximo de
64kbytes, y es así que un archivo .com es un
ejecutable que no ocupa mas de 64kbytes.
• Lo ejecutamos en una DOS-BOX (emulador de
DOS)
DOSBox
DOSBox
Lenguajes Máquina
• Un programa ejecutable es una secuencia de
1´s y 0´s. Es un archivo binario
• Cada máquina o arquitectura tiene su propio
conjunto de instrucciones con su propia
codificación binaria. (ver formato de
instrucción)
• Si dos máquinas distintas aceptan el mismo
archivo binario para ejecutarse, entonces son
compatibles binarias.
Lenguaje Ensamblador
• Puede haber varios lenguajes ensambladores
para una misma arquitectura, pero todos ellos
deben generar el mismo lenguaje máquina.
AT&T:
push %ebp
sub $0x8,%esp
movb $0x41,0xffffffff(%ebp)
Intel:
push ebp
sub esp, 0x8h
movb 0xffffffff(ebp), 0x41h
Código generado (cygwin y gcc)
.file
"holamundo.c"
.def
__main;
.endef
.section .rdata,"dr"
.scl
2;
.type
32;
.scl
2;
.type
32;
"GCC: (GNU) 5.4.0"
printf;
.scl
2;
.type
32;
.LC0:
.ascii "Hola mundo\0"
.text
.globl
main
.def
main;
.endef
.seh_proc
main
#include <stdio.h>
int main()
{
printf("Hola mundo");
return 0;
main:
pushq
.seh_pushreg
movq
.seh_setframe
subq
.seh_stackalloc
.seh_endprologue
call
leaq
call
movl
addq
popq
ret
.seh_endproc
.ident
.def
.endef
%rbp
%rbp
%rsp, %rbp
%rbp, 0
$32, %rsp
32
__main
.LC0(%rip), %rcx
printf
$0, %eax
$32, %rsp
%rbp
Muchos ensambladores x86
High Level Assembler
• Desarrollado por Randall Hyde
• Es bueno :
Speed. Assembly language programs are generally the fastest programs around.
Space. Assembly language programs are often the smallest.
Capability. You can do things in assembly which are difficult or impossible in HLLs.
Knowledge. Your knowledge of assembly language will help you write better
programs even when using HLLs.
• Es malo:
Assembly is hard to learn.
Assembly is hard to read and understand.
Assembly is hard to debug.
Assembly is hard to maintain.
Assembly is hard to write.
Assembly language programming is time consuming.
Improved compiler technology has eliminated the need for assembly language.
Today machines are so fast that we no longer need to use assembly.
If you need more speed you should use a better algorithm rather than switch to
assembly language.
Machines have so much memory today saving space using assembly is not
important.
Assembly language is not portable.
program HelloWorld;
#include("stdlib.hhf")
begin HelloWorld;
stdout.put( "Hello World" nl )
end HelloWorld;
HLA
• http://www.oopweb.com/Assembly/Documen
ts/ArtOfAssembly/VolumeFrames.html
• https://sourceforge.net/projects/hlav1/
• Desarrollado por Randall Hyde
• The High Level Assembler (HLA) is a 32-bit
80x86 assembly language that is portable
between Win32, Linux, and FreeBSD
Proceso para generar un ejecutable
Ensamblar, Compilar, Linkeditar, Cargar
• Preprocesar : Es el primer paso de la compilación en C.
Procesa includes, instrucciones condicionales y macros
• Ensamblar Lo mismo que Compilación pero partiendo de
un fuente escrito en ensamblador
• Compilar Produce código objeto , traduce instrucciones a
lenguaje máquina, ubia datos. Deja direcciones sin resolver.
Construye tabla de símbolos y un tabla de reubicación para
el siguiente paso
• Linkeditar Une uno o mas objetos y los combina para
formar el ejecutable. Resuelve referencias entre módulos.
Asigna direcciones a variables y funciones: este proceso se
llama reubicación.
• Cargar carga del ejecutable en memoria
Compilación, Linkedición y Carga
Compilación
• Muchos compiladores actuales aplican optimizaciones de
código, que van desde sencillas , como eliminación de
subespresiones comunces:
– x = cos(v)*(1+sin(u/2)) + sin(w)*(1-sin(u/2))
– Reemplaza por:
• t = sin(u/2)
• x = cos(v)*(1+t) + sin(w)*(1-t)
• A optimizaciónes bastante mas complejas como loop
unrolling (desenrolle de bucles), software pipelining o
incluso planificación de instrucciones que altera su orden
en el código fuente.
• Las optimizaciones merecen ser estudiadas antes de hacer
que el compilador las introduzca. Los parámetros –o1, -o2, o3… indican que optimizaciones introducirá el compilador
Compilación: de fuente a código
objeto
• Cuando el compilador termina su trabajo, obtiene un
código objeto, puede ser un código en ensamblador o no.
Hay opciones para generarlo (-S).
• El código binario resultante llamado normalmente código
objeto tiene algunas posiciones de memoria no definidas
totalmente: si yo especifico el modo directo para acceder a
una variable, el offset es relativo al segmento de datos
definido en el archivo compilado. Seguramente mi código
tendrá también referencias a funciones externas que el
compilador no conoce.
• O sea que hay referencias que se resuelven en tiempo de
compilación, y otras quedan pendientes para el siguiente
proceso.
Programas Objeto
• Son archivos que contienen información
sobre símbolos y direcciones que no pudo
resolver el ensamblador o compilador.
Enlazar, Linkeditar. Linker
• El linker (ld, ln o gcc) toma uno o mas archivos
objeto y los combina, resultando en un
archivo ejecutable con un único segmento de
código, datos, pila, etc.
• Al hacer esto, resuelve algunas referencias
que el compilador no pudo resolver pues eran
externas.
• Genera un ejecutable listo para ser cargado en
memoria por el sistema operativo.
Linkedición
• Para poder unir
todos los´objetos,
dentro de ellos hay
estructuras de datos
tales como tablas
de símbolos y tablas
de reubicación
Linkedición: un proceso complejo
• $ ld -dynamic-linker /lib/ld-linux.so.2 \
/usr/lib/crt1.o \ /usr/lib/crti.o \
/usr/lib/gcc/i486-linux-gnu/4.3/crtbegin.o \ L/usr/lib/gcc/i486-linux-gnu/4.3 hola.o \ -lgcc
-lgcc_eh \ -lc /usr/lib/gcc/i486-linuxgnu/4.3/crtend.o \ /usr/lib/crtn.o
• $ gcc hola.o
Comando nm
• Te permite ver la Tabla de Símbolos…
• nm a.out:
– T indica definida en el archivo objeto. La
dirección es el offset donde está.
Librerías: ¿printf?
• Varios programas ejecutando en un sistema pueden
requerir las mismas funciones standard como printf(),
malloc(), strcpy(), etc o otras
• Si cada programa usa la librería standard por ejemplo,
entonces tiene que contener una copia de ella en su
imagen. Y esto ocupa bastante espacio y degrada el
rendimiento
• Es mejor tener a cada programa referenciando una sola
instancia de la librería.
• Esto se llama compartir objetos.
• This is implemented during the linking process where
some of the objects are linked during the link time
whereas some done during the run time
(deferred/dynamic linking).
Librerías Estáticas y Dinámicas
• Librerías Estáticas:
– El término ‘statically linked’ significa que el programa
y su librería se enlazan juntas en tiempo de
linkedición
– Las librerías de objetos que se enlazan estáticamente
tipicamente tienen la extensión .a
– libc.a es la librería standard de objetos en C
• Librerías Dinámicas:
– Se enlazan en tiempo de ejecución con su referencia.
– Se pueden compartir entre distintos programas
ejecutándose (procesos )
– El linkeditor debe almacenar en el ejecutable las
ubicaciones de estas librerías externas.
– Libc.o es la librería de objetos en C
¿Como verlas?
• En linux:
$ gcc -Wall hola.c
$ ldd a.out libc.so.6 => /lib/libc.so.6 (0x40020000) /lib/ldlinux.so.2 => /lib/ld-linux.so.2 (0x40000000)
Ejecutables
• Son archivos binarios
• Según el SO pueden tener extensiones
– Windows: .exe, .com, .dll
– Unix/linux: no tienen. Podemos averiguar que son con el
comando file
Ejecutables
• Cada Sistema Operativo tiene su propio formato
para ejecutables.
• Por ejemplo, ELF es el formato de linux. Y PE
(Portable Executable) es de windows hoy.
Windows usa la extensión .exe. Linux ninguna
extensión.
• Todos los ejecutables, además de las secciones
propiamente del programa, contienen mas datos
para su carga en memoria.
Carga de programas
• El cargador es una herramienta del Sistema Operativo
• El proceso de cargar en memoria un programa conlleva varios
pasos:
1.
2.
3.
4.
5.
6.
7.
Leer la cabecera del ejecutable para determinar el tamaño de sus
segmentos de texto y datos y pila
Crear un espacio de direcciones para el programa (memoria
virtual?? No lo carga todo)
Copiar instrucciones y datos del archivo a su espacio de memoria
(ojo! Copia de disco a memoria RAM)
También pone en el stack los argumentos del programa
Inicializa los registros del procesador, y se le asigna al SP la dirección
del tope de la pila
Da control a una rutina de inicialización que copia argumentos del
programa de la pila a los registros y que invoca al main
Cuando finaliza la ejecución, el programa de inicialización devuelve
control al Sistema Operativo
Resumen
• Cada máquina tiene su propio lenguaje máquina
• Cada ensamblador/compilador entiende su
propio lenguaje fuente y genera el programa
objeto para la máquina donde se va a ejecutar.
• Cada Sistema Operativo tiene su propio formato
de ejecutable
• Cualquier mala combinación de esas cosas, da:
sementation fault. Por ejemplo, querer ejecutar
un elf bajo windows o un PE bajo linux
Resumen
• Compatibilidad binaria, es cuando ejecutamos un
programa compilado en otra máquina y … no da
error!!!
• Un programa puede ejecutar en una máquina sin error,
pero …. no devolver los resultados esperados….
• Errores:
–
–
–
–
–
Sintácticos: tiempo de compilación o ensamblaje
De librerías inexistentes: tiempo de linkedición
De incompatibilidad binaria: tiempo de ejecución
De lógica del programa: tiempo de ejecución
De acceso a zonas prohibidas: (puntero con valor cero):
tiempo de ejecución

Documentos relacionados