Universidad de Costa Rica
Facultad de Ingeniería
Escuela de Ciencias de
Tarea Programada #1
Compilación de un programa
Curso: Autómatas y
Compiladores CI- 1322
Profesor:
Adolfo Di Mare
Estudiantes:
Kathryn Jones Pérez A42856 kathrynster@gmail.com
Gustavo
Yong Morales A35791 tavoyong@gmail.com
Agosto 20 2007
Tabla
de contenidos
1. Introducción.................................................................................................3
2. Descripción del problema a
resolver...........................................................4
· Planteo......................................................................................................4
· Objetivos.................................................................................................4
· Requerimientos ......................................................................................5
3. Abstracción..........................................................................................................5
· Especificación del programa........................................................................5
4. Compilación del programa................................................................................5
5. Código C++………………………………………………….…………..6
6. Código Pascal…………………………………………………………...9
7. Análisis de
Resultados………………………………………………....13
8. Conclusiones…………………………………………………………..14
9. Bibliografía..............................................................................................14
Introducción
En
esta tarea a partir de un programa base se obtendrán dos programas uno en C++ y
otro en pascal, luego se compilaran en sus respectivo compiladores para obtener
el código ensamblador.
Se
analizara el código obtenido para documentarlo y luego compararlo con el código
fuente respectiva, a continuación se comparan los resultados de cada programa
entre si para obtener diferencias que serán presentadas en esta tarea.
La tarea se subirá a la siguiente página:
https://curso-automatas.angelfire.com/tarea1/DocTP1.htm
Descripción
del problema a resolver
Planteo:
A partir
de un bloque de código dado por el profesor en el enunciado obtendremos 2
programas, uno escrito en Pascal y otro en C++. Se deben escoger y usar 2
compiladores para obtener el lenguaje ensamblador para cada versión del
programa. Se debe de asegurar de quitar las opciones de optimización de código
a cada compilador antes de correrlo y obtener resultados.
Se debe tomar el código ensamblador que se ha
obtenido para cada versión del programa y se debe modificar incluyendo
comentarios explicativos que muestren la correspondencia entre el programa
fuente y el que produce cada compilador. Luego se deben comparar los resultados
obtenidos, y destacar las diferencias importantes que encuentren. Se debe de
hacer una análisis de los resultados obtenidos y describir las
conclusiones.
Objetivos:
El objetivo de la tarea es poder entender y analizar mas a fondo la
relación entre un código en un lenguaje de programación de alto nivel, con el
código generado por un compilar en lenguaje ensamblador.
Requerimientos:
Entre requerimientos principales
para la utilización de este programa se tienen:
·
Una computadora
con sus dispositivos, sistema operativo Windows y programas debidamente
instalados.
·
Un IDE C++,
utilizaremos Microsoft Visual Studio.Net 2005.
·
Un IDE
Pascal, como Turbo Pascal.
·
Internet para la
búsqueda de lo compiladores, lo cuales a su ves deben de ser compatibles con el
sistema operativo de la maquina.
Abstracción
Especificación del
programa:
El programa determina cuales son los números de Armstrong en un
intervalo determinado, este intervalo es determinado por una variable constante
dentro del programa. Un número de Armstrong es aquel donde la suma de los cubos
de los números que los componen es igual
al número en cuestión.
Compilación del programa
Borland C version 3.1
Free Pascal 2.0.4
C++:
ifndef ??version
?debug macro
endm
publicdll macro name
public name
endm
endif
?debug V 300h
?debug S "..\..\CODIGO.C"
?debug C
E968731F350E2E2E5C2E2E5C434F4449474F2E43
?debug C
E940A9C91817453A5C424333315C494E434C5544455C535444494F+
?debug C
2E48
?debug C
E940A9C91817453A5C424333315C494E434C5544455C5F44454653+
?debug C
2E48
?debug C
E940A9C91818453A5C424333315C494E434C5544455C5F4E46494C+
?debug C
452E48
?debug C
E940A9C91817453A5C424333315C494E434C5544455C5F4E554C4C+
?debug C
2E48
?debug C
E940A9C91817453A5C424333315C494E434C5544455C434F4E494F+
?debug C
2E48
_TEXT segment
byte public 'CODE'
_TEXT ends
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP
_DATA segment word
public 'DATA'
d@ label byte
d@w label word
_DATA ends
_BSS segment
word public 'BSS'
b@ label byte
b@w label word
_BSS ends
_TEXT segment byte public 'CODE'
?debug C
E8010E2E2E5C2E2E5C434F4449474F2E4368731F+
?debug C 35
?debug L 11
assume cs:_TEXT
_main proc near ; void main (){
?debug B
push bp
mov bp,sp
sub sp,6
push si
push di
?debug B
?debug L 12
mov word ptr [bp-6],3000; int
digito,suma,temp,numero,N=3000;
?debug L 13
call near ptr _clrscr ; clrscr(); limpia pantalla
?debug L 14
push word ptr [bp-6]
mov ax,offset DGROUP:s@
push ax
call near ptr _printf ;printf("Números
encontrados (1 .. %d)
que son de Armstrong: \n",N);
pop cx
pop cx
?debug L 15
mov ax,offset DGROUP:s@+54
push ax
call near ptr _printf;
printf("\n");
pop cx
?debug L
16
mov si,1 ; for (numero=1; numero<N;numero++)
jmp short @1@226
@1@58:
?debug L 17
xor di,di ; suma
= 0;
?debug L 18
mov word ptr [bp-4],si ; temp = numero;
jmp short @1@114
@1@86:
;inicio del método while
;while
(temp != 0){ // { suma de dígitos }
;digito
= temp % 10; // { al cubo }
?debug L
20
mov ax,word
ptr [bp-4]
mov bx,10
cwd
idiv bx
mov word ptr [bp-2],dx
?debug L 21
mov ax,word
ptr [bp-2] ; inicio de la operación suma =
suma +
; (digito * digito * digito);
imul word
ptr [bp-2]
imul word ptr [bp-2]
mov dx,di
add dx,ax
mov di,dx
?debug L 22
mov ax,word
ptr [bp-4];;inicio de la operación temp = temp / 10
mov bx,10
cwd
idiv bx
mov word ptr [bp-4],ax
@1@114:
?debug L 19
cmp word ptr [bp-4],0
jne short @1@86
?debug L 24
cmp di,si; if (suma == numero)
jne short @1@198
?debug L 25
push di
push si
mov ax,offset DGROUP:s@+56
push ax
call near ptr _printf ;printf("%d Suma de sus digitos al
cubo
; %d\n", numero,suma)
add sp,6
@1@198:
?debug L 16
inc si
@1@226:
cmp si,word ptr [bp-6]
jl short @1@58
;inicio
del método getchar();
?debug L 28
dec word ptr DGROUP:__streams
jl short @1@310
mov bx,word ptr DGROUP:__streams+10
inc word ptr DGROUP:__streams+10
mov al,byte ptr [bx]
mov ah,0
jmp short @1@338
@1@310:
mov ax,offset DGROUP:__streams
push ax
call near ptr __fgetc
pop cx
@1@338:
?debug L 29
pop di
pop si
mov sp,bp
pop bp
ret
?debug C
E6014E0402FAFF00066E756D65726F0404060004+
?debug C
74656D700402FCFF000473756D61040407000664+
?debug C 696769746F0402FEFF00
?debug E
?debug E
_main endp
?debug C E9
?debug C
FA00000000
_TEXT ends
_DATA segment
word public 'DATA'
s@ label byte
db 'N'
db 250
db 'meros encontrados (1 .. %d) que son de Armstrong: '
db 10
db 0
db 10
db 0
db '%d
Suma de sus digitos al cubo %d'
db 10
db 0
_DATA ends
_TEXT segment
byte public 'CODE'
_TEXT ends
public _main
extrn _clrscr:near
extrn __fgetc:near
extrn _printf:near
extrn __streams:word
_s@ equ s@
?debug C EA0109
?debug C
E31800000023010000
?debug C
EC055F6D61696E181800
?debug C
E31900000023010000
?debug C EB075F636C727363721900
?debug C E31A00000023040000
?debug C EB075F5F66676574631A00
?debug C
E31B00000023040001
?debug C
EB075F7072696E74661B00
?debug C
E31D0010001E01
?debug C
E31E000200150804
?debug C
E31C0000001A1D
?debug C EB095F5F73747265616D731C00
?debug C
E60446494C451D06000666706F735F7406060006+
?debug C 73697A655F740A0600
?debug C
E200056C6576656C040005666C6167730A000266+
?debug C
64020004686F6C640800056273697A6504000662+
?debug C
75666665721E0004637572701E0006697374656D+
?debug C
700A0005746F6B656E04C010000000
end
Pascal
.386p
LOCALS @@
DGROUP GROUP _BSS,_DATA
ASSUME CS:_CODE,ES:DGROUP,DS:DGROUP,SS:DGROUP
EXTRN U_SYSWIN32_OUTPUT
EXTRN FPC_WRITELN_END
EXTRN FPC_WRITE_TEXT_SINT
EXTRN FPC_WRITE_END
EXTRN FINALIZE$$OBJPAS
EXTRN INIT$$OBJPAS
EXTRN INIT$$CRT
EXTRN INIT$$DOS
EXTRN INIT$$SYSWIN32
EXTRN FPC_WRITE_TEXT_SHORTSTR
EXTRN FPC_INITIALIZEUNITS
EXTRN _CRT$$_CLRSCR
EXTRN FPC_IOCHECK
EXTRN FPC_DO_EXIT
EXTRN U_SYSWIN32_ISCONSOLE
EXTRN _CRT$$_READKEY
_CODE SEGMENT PARA PUBLIC USE32 'CODE'
PUBLIC _main
_main:
PUBLIC PASCALMAIN
PASCALMAIN:
PUBLIC program_init
program_init:
push ebp
mov ebp,esp
sub esp,4
mov byte ptr [U_SYSWIN32_ISCONSOLE],1
call FPC_INITIALIZEUNITS
call _CRT$$_CLRSCR Limpia
la pantalla
@@3:
lea edi,dword ptr [U_SYSWIN32_OUTPUT]
mov dword ptr [ebp-4],edi
push offset @@6
push dword ptr [ebp-4]
push 0
call FPC_WRITE_TEXT_SHORTSTR Imprime el texto
push dword ptr [ebp-4] “Numeros encontrados(1…”
call FPC_WRITE_END
push offset @@3
call FPC_IOCHECK
@@7:
lea edi,dword ptr [U_SYSWIN32_OUTPUT]
mov dword ptr [ebp-4],edi
push 3000
push dword ptr [ebp-4]
push 1
call FPC_WRITE_TEXT_SINT
push offset @@14
push dword ptr [ebp-4]
push 0
call FPC_WRITE_TEXT_SHORTSTR Imprime el texto
push dword ptr [ebp-4] “)que son de Armstrong”
call FPC_WRITELN_END
push offset @@7
call FPC_IOCHECK
@@15:
lea edi,dword ptr [U_SYSWIN32_OUTPUT]
mov dword ptr [ebp-4],edi
push dword ptr [ebp-4]
call FPC_WRITELN_END
push offset @@15
call FPC_IOCHECK
mov word ptr [_NUMERO],1 numero = 1.. aquí comienza el
@@18: for
mov word
ptr [_SUMA],0 suma = 0
mov di,word
ptr [_NUMERO]
mov word ptr [_TEMP],di temp = numero
jmp @@26
@@25:
movsx eax,word ptr [_TEMP] Cuerpo del While
mov edi,10
cdq
idiv edi digito:=temp
MOD 10;
mov word
ptr [_DIGITO],dx suma:=
suma +(digito*digito
movsx eax,word ptr [_DIGITO] *digito);
movsx edx,word ptr [_DIGITO]
imul edx,eax temp:=
temp DIV 10;
movsx eax,word ptr [_DIGITO]
imul eax,edx
movsx edx,word ptr [_SUMA]
add edx,eax
mov word ptr [_SUMA],dx
movsx eax,word ptr [_TEMP]
mov edi,10
cdq
idiv edi
mov word ptr [_TEMP],ax
@@26:
movsx eax,word ptr [_TEMP] While temp <> 0 DO BEGIN{
test eax,eax
jne @@25
movsx eax,word ptr [_SUMA]
movsx edx,word ptr [_NUMERO]
cmp edx,eax if
suma = numero {
jne @@35 else{
->brinca a @@35
@@36:
lea edi,dword ptr [U_SYSWIN32_OUTPUT]
mov dword
ptr [ebp-4],edi
movsx eax,word ptr [_NUMERO]
push eax
push dword ptr [ebp-4] Imprime en pantalla:
push 0
call FPC_WRITE_TEXT_SINT (numero, “Suma
de
push offset @@41 digitos al cubo”, suma)
push dword ptr [ebp-4]
push 0
call FPC_WRITE_TEXT_SHORTSTR
movsx eax,word ptr [_SUMA]
push eax
push dword ptr [ebp-4]
push 0
call FPC_WRITE_TEXT_SINT
push dword ptr [ebp-4]
call FPC_WRITELN_END
push offset @@36
call FPC_IOCHECK
@@35:
cmp word ptr [_NUMERO],3000
jge @@17 Vuelve
a repetir el for
inc word ptr [_NUMERO]
jmp @@18
@@17:
call _CRT$$_READKEY readkey
call FPC_DO_EXIT
leave
ret
ALIGN 16
_CODE ENDS Fin del codigo
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
DB "FPC 1.00 [2000/07/11] for i386 -
WIN32"
ALIGN 4
PUBLIC FPC_RESOURCESTRINGTABLES
FPC_RESOURCESTRINGTABLES DD 0
PUBLIC INITFINAL
INITFINAL DD 4,0
DD offset INIT$$SYSWIN32
DD 0
DD offset INIT$$OBJPAS
DD offset FINALIZE$$OBJPAS
DD offset INIT$$DOS
DD 0
DD offset INIT$$CRT
DD 0
PUBLIC HEAPSIZE
HEAPSIZE DD 2097152
_DATA ENDS
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
@@6 DB 26,"N",250,"meros
encontrados (1 .. ",0
@@14 DB 23,")
que son de Armstrong:",0
@@41 DB 29,"
Suma de sus d",237,"gitos al cubo ",0
_DATA ENDS
_DATA SEGMENT PARA PUBLIC USE32 'DATA'
_DATA ENDS
_BSS SEGMENT PARA PUBLIC USE32 'BSS'
_NUMERO DB 2
DUP(?)
_SUMA DB 2
DUP(?)
_DIGITO DB 2 DUP(?)
_TEMP DB 2 DUP(?)
PUBLIC HEAP
HEAP DB 2097152 DUP(?)
_BSS ENDS
END
Análisis de resultados:
Conclusiones
El
código en Ensamblador de C++ utiliza registros de 64 bits mientras que Pascal
al ser más viejo, utiliza registros de 32 bits para realizar sus operaciones.
El lenguaje generado a partir de C++ es más directo
que el código generado por pascal, no utiliza nombres significativos para las
variables; sin embargo si para los métodos y funciones. En el caso del lenguaje
generado a partir de Pascal las variables utilizadas son casi las mismas que el código original, haciéndolo fácil de leer y
entender.
Guía para la documentación, Prof. Adolfo Di Mare