Pasar a código ensamblador [Ayuda]

Iniciado por leogtz, 6 Diciembre 2011, 04:46 AM

0 Miembros y 1 Visitante están viendo este tema.

leogtz

Bueno, les cuento. Estoy haciendo un compilador para un lenguaje de programación que inventé (En realidad es una ****, pero bueno, algo es algo, es como parte de un trabajo final de una materia que estoy llevando en la universidad, tengo que entregarlo dentro de una semana), ya hice mi analizador léxico, el analizador sintáctico, el semántico y demás, ahora estoy en la parte de generación de código. Hice un algoritmo que genera código ensamblador basándose en mi árbol sintáctico. El problema es que genera un código ensamblador que no es "ensamblador" :p, lo simula, ya que NO sé ensamblador. Entonces, necesito ayuda para pasar de algo como esto:

inicio X
entero a = 1 + 2 * 3 - 5
fin;


A esto:

mov R0,#1 ; Movimiento
mov R1,#2 ; Movimiento
mov R2,#3 ; Movimiento
mul R1,R2     ;  Multiplicamos
add R0,R1     ; Sumamos
mov R1,#5 ; Movimiento
sub R0,R1        ; Restamos
mov a,R0    ; fin de la sentencia

SENTENCIA PARA MOSTRAR a


Que es lo que genero con el algoritmo que hice (sé que no es muy eficiente), ¿cómo quedaría en assembly real y qué más necesito para poder generar el ejecutable?

Disculpen mi ignorancia en este rubro pero es que estoy totalmente perdido en esto, necesito un poco de ayuda.

Saludos.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

.:UND3R:.

#1
Cita de: Leo Gutiérrez. en  6 Diciembre 2011, 04:46 AM
Bueno, les cuento. Estoy haciendo un compilador para un lenguaje de programación que inventé (En realidad es una ****, pero bueno, algo es algo, es como parte de un trabajo final de una materia que estoy llevando en la universidad, tengo que entregarlo dentro de una semana), ya hice mi analizador léxico, el analizador sintáctico, el semántico y demás, ahora estoy en la parte de generación de código. Hice un algoritmo que genera código ensamblador basándose en mi árbol sintáctico. El problema es que genera un código ensamblador que no es "ensamblador" :p, lo simula, ya que NO sé ensamblador. Entonces, necesito ayuda para pasar de algo como esto:

inicio X
entero a = 1 + 2 * 3 - 5
fin;


A esto:

mov R0,#1 ; Movimiento
mov R1,#2 ; Movimiento
mov R2,#3 ; Movimiento
mul R1,R2     ;  Multiplicamos
add R0,R1     ; Sumamos
mov R1,#5 ; Movimiento
sub R0,R1        ; Restamos
mov a,R0    ; fin de la sentencia

SENTENCIA PARA MOSTRAR a


Que es lo que genero con el algoritmo que hice (sé que no es muy eficiente), ¿cómo quedaría en assembly real y qué más necesito para poder generar el ejecutable?

Disculpen mi ignorancia en este rubro pero es que estoy totalmente perdido en esto, necesito un poco de ayuda.

Saludos.

No entiendo muy bien que es lo que quieres hacer deseas saber como quedaría
inicio X
entero a = 1 + 2 * 3 - 5
fin;


en ASM?

Si es así a los valores debes asignarle registros de propósito general por recomendación de 32 bits en código ASM

Código (asm) [Seleccionar]
TITLE prueba (prueba.asm)
INCLUDE c:\masm32\include\Irvine32.inc
INCLUDELIB c:\masm32\lib\kernel32.lib
INCLUDELIB c:\masm32\lib\Irvine32.lib
INCLUDELIB c:\masm32\lib\User32.lib
.data
RESULTADO DWORD ?        ; Variable sin inicializar tipo DWORD (4 bits)
.code
main PROC
mov ecx,3                         ; ECX = 3
mov eax,2                         ; EAX = 2
mov ebx,5                         ; EBX = 5
mul ecx                             ; multiplica el valor de EAX con ECX y lo guarda en EAX
not ebx                              ; invierte el valor de EBX (complemento a dos), invierte los bits y le suma 1 bit
add eax,ebx                       ; suma EAX = 3*2 con EBX = -5 y lo almacena en eax
inc eax                               ; aumenta en 1 el contenido de EAX
mov RESULTADO,eax          ; mueve a la variable RESULTADO el valor de EAX
exit
main ENDPROC
END main


utilicé librerías que facilitan la programación en ASM como es el caso de utilizar exit ya que sin estas librerías se debería utilizar la API ExitProcess junto con la directiva INVOKE

en cuanto para poder generar el ejecutable necesitas realizar dos cosas:

1)ensamblar
2)linkear

ensamblar consiste en transformar el código de fuente en lenguaje máquina pero sin incluir las librerías esto generaría un archivo llamado código objeto (.obj)

linkear consiste en juntar las librerías que haz utilizado junto con el programa, este generaría el .exe

para aquello puedes optimizarlo con IDE como MASM32 que incluye la opción build all así generaría el .exe inmediatamente

también esto puedes hacer desde batch una vez instalado el MASM32:

Código (bash) [Seleccionar]
echo off
:inicio
cls
set path=%PATH%;c:\masm32\bin
echo Introduzca el nombre del archivo (ej prueba.asm):
set /P file=
cls
ml /Cp /coff %file% /link /subsystem:console
pause
goto inicio

(*este es tu fuerte  :P)

con eso te ahorrarías tener que entrar al IDE de MASM32

Saludos

EI: juntando mensajes.

En cuanto a las bibliotecas estas no vienen por defecto en MASM32 deberías bajarla de la siguiente página:
http://kipirvine.com/asm/examples/IrvineExamplesVS2005.exe

Un autoextraible que contiene el .INC y las .LIB incluidas en el ejemplo

(solo por que me haz ayudado en batch jeje)

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

leogtz

¡Gracias!

Pero bueno, la idea sería seguir el algoritmo (ya que no solo será esa expresión, sino que pudiera ser cualquier, incluso expresiones entre paréntesis y demás), que hice, mira:

inicio X
entero a = 1 + 2 * 3 - 5
fin;


Eso da como resultado "2", y sería seguir algo así:

mov R0,#1 ; Movemos el número "1" al registro R0
mov R1,#2 ; Movemos el número "2" al registro R1
mov R2,#3 ; Movemos el número "3" al registro R2
mul R1,R2     ;  Multiplicamos el registro R1 y R2, quedándose el resultado en R1, ya tenemos un 6
add R0,R1     ; Sumamos el registro R0 y R1, quedándose el resultado en R0, ya tenemos un 7
mov R1,#5 ; Movemos el número "5" al registro R1
sub R0,R1        ; Restamos el registro R0 y el registro R1, quedándonos un 2
mov a,R0    ; Asignamos el resultado a "a" (o a cualquier otra variable, no importa) ....



Sería fácil pasar eso a ASM?

Gracias por la ayuda.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

x64core

Cita de: Leo Gutiérrez. en  6 Diciembre 2011, 05:25 AM
¡Gracias!

Pero bueno, la idea sería seguir el algoritmo (ya que no solo será esa expresión, sino que pudiera ser cualquier, incluso expresiones entre paréntesis y demás), que hice, mira:

inicio X
entero a = 1 + 2 * 3 - 5
fin;


Eso da como resultado "2", y sería seguir algo así:

mov R0,#1 ; Movemos el número "1" al registro R0
mov R1,#2 ; Movemos el número "2" al registro R1
mov R2,#3 ; Movemos el número "3" al registro R2
mul R1,R2     ;  Multiplicamos el registro R1 y R2, quedándose el resultado en R1, ya tenemos un 6
add R0,R1     ; Sumamos el registro R0 y R1, quedándose el resultado en R0, ya tenemos un 7
mov R1,#5 ; Movemos el número "5" al registro R1
sub R0,R1        ; Restamos el registro R0 y el registro R1, quedándonos un 2
mov a,R0    ; Asignamos el resultado a "a" (o a cualquier otra variable, no importa) ....



Sería fácil pasar eso a ASM?

Gracias por la ayuda.

el codigo es el mismo que el primero :P
bueno para hacer un compilador de un X lenguajes me imagino que debes de saber bien el lenguaje al que debes de "convertirlo" :P
o podrias hacer algo asi:
digamos que el "lenguaje" seria C++... bueno tomo ese como referencia porque cada instruccion o expresion , sentencias va de ultimo el ";"
algo asi deberia ser recomandado tu lenguaje :P y en el texto que encuentre antes del ";", lo "tome" y convierta a ensamblador y eso tomando
en cuenta la precedencia, y tambien que algunos se ejecutan de izquierda a derecha o de derecha a izquierda pero eso me imagino que ya
lo haz decidido en tu lenguaje. bueno yo a penas empiezo en asm asi que al menos eso te puedo decir :P aunque eso creo que ya lo sabes :P
igual esperamos a Eternal Idol, _Enko que son buenos en asm


por cierto...
@UND3R
porque la instruccion NOT? no entendi :P
de hecho yo hice el codigo asi:


.data
   VAR DWORD ?
.code
   ; VAR = 1 + 2 * 3 - 5
   
   mov eax,2
   mov edx,3
   mul edx
   sub eax,5
   add eax,1
   mov VAR,eax

se me ocurrio saber como saber o que codigo o que formas son mas rapidas :P



Eternal Idol

Cita de: Leo Gutiérrez. en  6 Diciembre 2011, 04:46 AMQue es lo que genero con el algoritmo que hice (sé que no es muy eficiente), ¿cómo quedaría en assembly real y qué más necesito para poder generar el ejecutable?

Depende del procesador (incluso en PC puede ser de 16, 32 o 64 bits). Para poder generar un ejecutable necesitas, ademas de comprender el modo real o el protegido (o long para 64 bits), el formato del ejecutable que quieras generar. No es lo mismo un COM (sin cabecera, puro codigo, lo mas simple y limitado) que un PE (ejecutable para Windows) o un ELF (ejecutable para Unix).

PD. Por favor no traigan mas la libreria esa de Irvine sin necesidad ...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

_Enko

Tampoco puedes escribir codigo en assembly y pensar que cualquier ensamblador te lo tomaria.
Es decir, entre los distintos ensambladores hay ciertas diferencias. Asi que tendras que elegir que ensamblador usaras como back-end de tu compilador.

En EntryPoint estan enlazados:
http://foro.elhacker.net/asm/entry_point-t256455.0.html

cualquiera te serveria, lo unico a resaltar es que con masm32 solo podrias producir ejecutables para windows. Con Nasm/Fasm no tienes esa limitacion.

Saludos.

leogtz

Cita de: _Enko en  6 Diciembre 2011, 13:54 PM
Tampoco puedes escribir codigo en assembly y pensar que cualquier ensamblador te lo tomaria.
Es decir, entre los distintos ensambladores hay ciertas diferencias. Asi que tendras que elegir que ensamblador usaras como back-end de tu compilador.

En EntryPoint estan enlazados:
http://foro.elhacker.net/asm/entry_point-t256455.0.html

cualquiera te serveria, lo unico a resaltar es que con masm32 solo podrias producir ejecutables para windows. Con Nasm/Fasm no tienes esa limitacion.

Saludos.

Entonces me interesa, ya que el compilador corre tanto en Windows y Linux, y necesito que sea portable. Voy a tener que leer sobre nasm/fasm, como se hacen operaciones aritméticas básicas.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com