Site hosted by Angelfire.com: Build your free website today!

 

Universidad de Costa Rica

 

 

 

Facultad de Ingeniería

 

 

 

Escuela de Ciencias de la Computación e Informática

 

 

 

 

 

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.

 

 

Bibliografía

Guía para la documentación, Prof. Adolfo Di Mare