[Guía NASM] Introducción a Netwide Assembler (Partes 1 y 2) (Descarga PDF)

Iniciado por yoyomismo, Abril 10, 2013, 11:23:11 AM

Tema anterior - Siguiente tema

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

Publicado originalmente para No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, autoría propia.

Este es un manual que comencé a escribir hace tiempo, acerca de Netwide Assembler.

Atención: dudas y mensajes sobre este tema se responderán por mensaje privado o mediante la creación de un nuevo hilo.

Introducción a Netwide Assembler (NASM)

Actualmente, es muy difí­cil encontrar programas escritos completamente en Assembler, sin embargo, son utilizados por su portabilidad y facilidad de uso, además, al estar creado en un lenguaje de programación de nivel bajo, no tiene empaquetado ni tanta  basura que puede contener otro programa creado, por ejemplo, en VB, lo que puede generar un ejecutable de apenas 2'5Kb, cuando el mismo programa, en VB, serí­a de 21Kb. Ya veremos más adelante estos datos.

¿Por qué necesitamos aprender Assembler?

->   Genera un código más rápido y pequeño que otro programa escrito en otro lenguaje de alto nivel
->   Para ciertas plataformas, los lenguajes de alta programación son ineficientes, debido a restricciones del hardware (Ej.: Sistemas embebidos)
->   Permite acceder al Hardware directamente (Ej.: Sistemas operativos)
->   Conocerás como funciona completamente un PC internamente

Registros

Registros de datos              EAX EBX ECX EDX
Punteros de pila                  ESP EBP
Registros de í­ndice              EDI ESI
Registros de segmento       FS CS DS ES SS

EAX: También llamado acumulador

EBX: Puede ser usado como registro base de direccionamiento        (por ejemplo, para apuntar a direcciones de memoria con el)

ECX: Usado como contador (ciclos, rotaciones...)

EDX: Registro de datos, a veces usado con EAX en instrucciones especiales.
Los sistemas de 32 bits, están construidos por registros de 16 bits, y estos a su vez, están divididos en  subsegmentos  de 8 bits, que a su vez, están formados por dos códigos hexadecimales, de 4 bits cada uno (Cada bit es un impulso eléctrico, positivo (1) o negativo (2)). La siguiente tabla muestra un ejemplo:

##############
# Segunda entrega  #
##############

-No hay forma de acceder a los 16 bits superiores.

Estas direcciones requieren un número de 20 bits, el cual, no cabrá en un registro de 16 bits. Desde la llegada de Intel, se usaban 2 valores de 16 bits (32 bit) para determinar una dirección. Los valores del seleccionador deben estar en registros de segmento, y el segundo valor de 16 bits, es el desplazamiento (Offset). Se puede obtener la dirección mediante la siguiente formula:
16 * Seleccionador + Desplazamiento

Una curiosidad es la forma en la que la máquina obtiene un número hexadecimal a partir de uno decimal. He aquí­ la fórmula:
Decimal: 31278
31278:16 = 1954 resto= 14 (E)
1954:16 = 122 resto= 2 (2)
122:16 = 7 resto= 10 (A)
7:16 = 0 resto= 7 (7)
7A2E (Hexadecimal)

Como vemos, realiza algo similar a una conversión decimal binaria, pero usando 16 para obtener un número valido para continuar dividiendo, y el resto, el valor hexadecimal. Pueden ponerlo en práctica.

Operadores lógicos
Hay de 4 tipos, y se representan como en la siguiente tabla:

And: Vale 1 si ambos bites están a 1
1 | 1 = 1
1 | 0 = 0
0 | 0 = 0
0 | 1 = 1

Or: Vale 1 si algún bit vale 1
1 | 1 = 1
1 | 0 = 1
0 | 0 = 0
0 | 1 = 1

Xor: Vale 1 si los bits son diferentes, y 0 si no lo son
1 | 1 = 0
1 | 0 =1
0 | 0 =0
0 | 1 =1
 
Not: Invierte el valor del bit
Not 1 = 0
Not 0 = 1


Flags
Son registros especiales, en donde se guardan los resultados de la última operación matemática, o de comprobación. No se almacenan resultados numéricos, sino su estado.

Aunque es un registro de 16 bits, sólo algunos de ellos tienen significado. Los otros adquieren valores indeterminados, y se dice que son bits reservados; un programa no debe tocarlos, pues aunque un equipo dado puede que no los use, otros micros podrían manipularlos internamente, con resultados impredecibles.

    * CF Carry Flag o indicador de acarreo. Normalmente indica si "nos llevamos algo" despues de haber sumado o restado.
    * OF Overflow Flag o indicador de desbordamiento. Si después de una operación el resultado no cabe en el tamaño del registro, se pone a 1.
    * ZF Zero Flag o indicador de cero. Si el resultado da 0 se pone a 1.
    * SF Sign Flag o indicador de signo. Si el resultado es negativo se pone a 1.
    * PF Parity Flag o indicador de paridad. Con algunas operaciones lógicas o aritméticas se pone a 1 si el resultado es par.
    * AF Auxiliary Flag o indicador auxiliar. Se usa para operaciones BCD (si es que éstas valen para algo)
    * DF Direction Flag o indicador de dirección. Se usa en operaciones llamadas "de cadena", indicando el sentido (ascendente o descendente) en que se recorre la memoria. (Este flag es más divertido de lo que parece.)
    * IF Interrupt Flag o indicador de interrupciones. Cuando se pone a 1 se permiten las interrupciones, a 0 se ignoran; se dice que se enmascaran. Hay no obstante algunas muy especiales que pasan del flag; por ejemplo, si arrancas (físicamente, me refiero; coger con la mano y zás!) una tarjeta de RAM con el trasto encendido, la interrupción que salta -alerta roja, inmersión, inmersión, auuuuu- pasa de este flag olímpicamente (algo así no se puede pasar por alto bajo ninguna circunstancia).
    * TF Trap Flag o indicador de trampa (para ejecución paso a paso, como en los depuradores; podemos olvidarnos de él)


###############
# Tercera entrega  #
###############

Tipos de datos

Lo que hace diferente a Assembler frente a otros lenguajes, es que tu mismo puedes indicar el tamaño reservado a una variable. Existen 4 tipos, dependiendo del tamaño a ocupar:
-> BYTE    - Reserva 8 bit                       - 2 ^ 8  = 256
-> WORD   - Reserva 16 bit                     - 2 ^ 16 = 65536
-> DWORD - Double Word, reserva 32 bit   - 2 ^ 32 = 4294967296
-> QWORD - Quad Word, reserva 64 bit     - 2 ^ 64 = 18446744073709551616 (Únicamente usado en plataformas X64)

Juegos de instrucciones

Bueno, esta lista la obtuve de No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, ya que se trata de una gran lista, dependiendo del sistema que utilices. Esta se basa en arquitecturas 80X86:

acum                     uno de los acumuladores: AX o AL.
reg                        cualquiera de los registros
segreg                   uno de los registros de segmento
r/m                        uno de los operandos generales: registro, memoria, basado, indexado o basado-indexado
inmed                    constante o símbolo de 8 o 16 bits
mem                     un operando de memoria: símbolo, etiqueta, variable.
etiqueta                 etiqueta de instrucciones.
src                        fuente en operaciones de cadena
dest                      destino en operaciones de cadena.

8086/8088

AAA                                Ajuste ASCII para adición.
AAD                                Ajuste ASCII para división.
AAM                                Ajuste ASCII para multiplicación.
AAS                                Ajuste ASCII para división.
ADC   acum, inmed           Suma con acarreo.
r/m,inmed
r/m, reg
reg, r/m
ADD  acum,inmed             Suma.
r/m,inmed
r/m, reg
reg, r/m
AND  acum,inmed             Operación AND a nivel bit.
r/m,inmed
r/m, reg
reg, r/m
CALL etiqueta                  Llamado.
r/m
CBW                               Convierte byte apalabra.
CLC                                 Limpia bandera de acarreo.
CLD                                 Limpia bandera de dirección.
CLI                                  Limpia bandera de interrupción.
CMC                                Complementa bandera de acarreo.
CMP  acum,inmed            Comparación
r/m,inmed
r/m, reg
reg, r/m
CMPS  src,dest                Comparación de cadenas.
CMPSB                           Compara cadenas byte por byte.
CMPSW                          Compara cadenas palabra por palabra.
CWD                               Convierte palabra a palabra doble.
DAA                                Ajuste decimal para adición.
DAS                                Ajuste decimal para substracción.
DEC   r/m                         Decremento.
reg
DIV    r/m                         División.
ESC  inmed, r/m               Escape con 6 bits.
HLT                                 Alto.
IDIV  r/m                          División entera.
IMUL r/m                         Mutiplicación entera.
IN      accum,inmed          Entrada desde puerto.
acum, DX
INC    r/m                         Incremento.
          reg
INT3                                Interrupción3 codificada como un byte.
INT    inmed                     Interrupción0-255.
INTO                               Interrupción en overflow.
IRET                                Retorno de interrupción.
JMP etiqueta                    Brinco incondicional.
LAHF                               Carga AH con las banderas.
LDS  r/m                          Carga DS.
LEA   r/m                         Carga la dirección.
LES  r/m                          Carga ES.
LOCK                              Cierra bus.
LODS  src                        Carga cadena.
LODSB                            Carga byte de cadena en  AL.
LODSW                           Carga palabra de la cadena en  AX.
LOOP  etiqueta                Ciclo.
LOOPE  etiqueta              Ciclo mientras igual.
LOOPNE  etiqueta            Ciclo mientras no igual.
LOOPNZ  etiqueta            Ciclo mientras no cero.
LOOPZ  etiqueta               Ciclo mientras cero.
MOV  acum,mem             Mueve un valor del segundo al primer operando
r/m,inmed
mem, acum
r/m, reg
r/m,segreg
reg, inmed
reg,r/m
segreg,r/m
MOVS  dest, src               Mueve cadena.
MOVSB                           Mueve cadena byte por byte.
MOVSW                          Mueve cadena palabra por palabra.
MUL  r/m                         Multiplicación.
NEG  r/m                          Niega(complemento a 2).
NOP                                Operación ociosa.
NOT  r/m                          Invierte valores de bits (complemento a 1).
OR   acum, inmed             Operación OR a nivel de bit.
r/m,inmed
r/m, reg
reg,r/m
OUTDX, accum                Salida por el puerto dado por el primer operando.
inmed, acum            (inmediato de 8 bits)
POP  r/m                         Recupera valor de la pila.
reg
segreg
POPF                              Recupera banderas.
PUSH  r/m                       Guarda valor en la pila.
reg
segreg
PUSHF                            Guarda banderas.
RCL  r/m,1                       Rotación a la izquierda con acarreo.
r/m,CL
RCR  r/m, 1                      Rotación a la derecha con acarreo.
r/m, CL
REP                                 Repite.
REPE                               Repite si igual.
REPNE                            Repite si no igual.
REPNZ                             Repite si no cero.
REPZ                               Repite si cero.
RET  [inmed]                    Regresa después de recuperar bytes de la pila.
ROL r/m,1                        Rotación a la izquierda.
r/m, CL
ROR r/m,1                        Rotación a la derecha.
r/m, CL
SAHF                              Carga banderas con el valor de AH.
SAL  r/m, 1                      Desplazamiento aritmético a la izquierda.
r/m, CL
SAR  r/m, 1                      Desplazamiento aritmético a la derecha.
r/m, CL
SBB  acum, inmed            Substracción con acarreo.
r/m,inmed
r/m, reg
reg,r/m
SCAS dest                       Explora cadena.
SCASB                            Explora cadena para el byte en AL.
SCASW                           Explora cadena por la palabra en AX.
SHL  r/m, 1                      Desplazamiento a la izquierda.
r/m, CL
SHR  r/m, 1                      Desplazamiento a la derecha.
r/m, CL
STC                                 Fija bandera de acarreo.
STD                                 Fija bandera de dirección.
STI                                  Fija bandera de interrupción.
STOS dest                       Guarda cadena.
STOSB                            Guarda byte en AL en la cadena.
STOSW                           Guarda palabra en AX en la cadena.
SUB  accum, inmed          Substracción.
r/m,inmed
r/m, reg
reg,r/m
TEST acum, inmed           Comparación.
r/m,inmed
r/m, reg
reg,r/m
WAIT                               Aguarda.
XCHG acum, reg              Intercambio.
r/m,inmed
r/m, reg
reg,r/m
XLAT                               Traduce.
XOR acum, reg                 Operación XOR a  nivel bit.
r/m,inmed
r/m, reg
reg,r/m

8087
F2XM1                             Calcula 2x-1.
FABS                              Toma valor absoluto del tope de la pila.
FADD  mem                     Suma real.
FADD  ST,ST(i)                Suma real desde la pila.
FADD  ST(i),ST                Suma real a la pila.
FADDP  ST(i), ST             Suma real y saca de pila.
FBLD  mem                     Carga un decimal empacado de 10 bytes en  lapila.
FBSTP  mem                   Almacena un decimal empacado de 10 bytes y saca de pila.
FCHS                              Cambia signo del valor en el tope de la pila.
FCLEX                             Borra las excepciones después de un WAIT.
FCOM                              Compara real.
FCOM  ST                       Compara real con el tope de la pila.
FCOM  ST(i)                    Compara real con la pila.
FCOMP                           Compara real y saca de pila.
FCOMP  ST                     Compara real con el tope dela pila y saca de pila.
FCOMP  ST(i)                  Compara real con el tope de la pila y saca.
FCOMPP                         Compara real y saca dos valores de la pila.
FDECSTP                        Decrementa el apuntador de la pila.
FDISI                               Deshabilita las interrupciones después de un WAIT.
FDIV  mem                      División real.
FDIV  ST,ST(i)                 División real desde la pila.
FDIV  ST(i), ST                División real en la pila.
FDIVPST(i), ST                División real sacando valor de la pila.
FDIVR                             División real invertida.
FDIVR  mem                    División real invertida desde memoria.
FDIVR  ST, ST(i)              División real invertida desde la pila.
FDIVR  ST(i), ST              División real invertida desde la pila.
FDIVRPST(i), ST              División con un real invertido y sacando valor de la pila.
FENI                                Habilita interrupciones después de un WAIT.
FFREE                             Libera elemento dela pila.
FIADD mem                     Suma entera de un número de2 ó 4 bytes.
FICOM  mem                   Compara enteros de 2 ó 4 bytes y saca de la pila.
FICOMP mem                  Compara entero de 2 ó4 bytes y saca de pila.
FIDIV mem                      División entera.
FDIVR mem                     División entera invertida.
FILD mem                        Carga un entero de 2, 4 u 8 bytes en la pila.
FIMUL  mem                    Multiplicación entera de 2 ó 4 bytes.
FINCSTP                         Incrementa el apuntador de la pila.
FINIT                               Inicializa el procesador después de WAIT.
FIST  mem                       Almacena entero de 2 ó 4 bytes.
FISTP  mem                    Almacena entero de 2, 4 u 8 bytes y saca de la pila.
FISUB  mem                    Resta entero de 2 ó 4 bytes.
FISUBR  mem                  Resta entera de 2 ó 4 bytes invertida.
FLD  mem                        Carga real de 4, 8 ó 10 bytes en la pila.
FLD1                               Pone +1.0 en el tope de la pila.
FLDCW mem                   Carga la palabra de control.
FLDENV  mem                 Carga entorno 8087 (14 bytes).
FLDL2E                           Cargalog2 e en el tope dela pila.
FLDL2T                           Cargalog2 10en el tope de la pila.
FLDLG2                           Cargalog102 en el tope de la pila.
FLDLN2                           Cargaloge2 en el tope de la pila.
FLDPI                              Carga p en el tope dela pila.
FLDZ                               Carga +0.0 en el tope de la pila.
FMUL                              Multiplicación real.
MUL  mem                       Multiplicación real desde memoria.
FMUL  ST, ST(i)               Multiplicación real desde pila.
FMUL  ST(i), ST               Multiplicación real a la pila.
FMULP  ST, ST(i)            Multiplicación real y saca de la pila.
FNCLEX                          Borra excepciones sin WAIT.
FNDISI                            Inhabilita interrupciones sin WAIT.
FNENI                              Habilita interrupciones sin WAIT.
FNINIT                             Inicializa procesador sin WAIT.
FNOP                              Operación nula.
FNSAVE  mem                 Salva estado 8087 (94 bytes) sin WAIT.
FNSTCW  mem                Almacena la palabra de control sin WAIT.
FNSTENV  mem               Guarda el entorno 8087 sin WAIT.
FNSTSW mem                 Almacena el estado8087 sin WAIT.
FPATAN                          Función arcotangente parcial.
FPREM                            Residuo parcial.
FPTAN                            Función tangente parcial.
FRNDINT                         Redondea a entero
FRSTOR mem                  Restablece estado8087 (94 bytes)
FSAVE mem                    Conserva el estado8087 (94 bytes).
FSCALE                          Escala
FSQRT                            Raíz cuadrada
FST                                 Almacena real.
FST  ST                           Almacena real desde el tope de la pila.
FST  ST(i)                        Almacena real desde lapila.
FSTCW   mem                 Almacena palabra de control  con WAIT.
FSTENV  mem                 Guarda el entorno 8087 después de WAIT.
FSTP  mem                     Guarda real de 4, 8 ó 10 bytes y saca de la pila.
FSTSW  mem                  Almacena la palabra de estado depués de WAIT.
FSUB                              Substracción real.
FSUB mem                      Substracción real desde memora.
FSUB ST, ST(i)                Substracción real desde la pila.
FSUB ST(i), ST                Substracción real a la pila.
FSUBPST, ST(i)               Substrae real y saca de pila.
FSUBR                            Substracción real invertida.
FSUBR  mem                   Substracción real invertida desde memoria.
FSUBR  ST,ST(i)              Substracción real invertida desde la pila.
FSUBR  ST(i), ST             Substracción real invertida a la pila.
FSUBRPST(i), ST            Substracción real invertida a la pila y saca.
FTST                               Prueba el tope dela pila.
FWAIT                             Aguarda que la última operación 8087 termine.
FXAM                              Examina el elemento del tope de la pila.
FXCH                              Intercambia contenido de los elementos de la pila.
FFREEST                         Intercambia el elemento del tope de la pila.
FFREEST(i)                      Intercambia el elemento del tope de la pila y el i-ésimo elemento.
FXTRACT                        Extrae el exponente y significando.
FYL2X                             Calcula Y log2 X.
FYL2PI                            Calcula Y log2 (x+1) 
CPH: Cibergolen
Otros: Yo-Mismo

Visitame en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

80186/80188/80286 (modo no protegido)

BOUND  reg, mem            Detecta valor fuera de rango.
ENTER inmed16, inmed8   Hace elemento en la pila para llamada a  procedimiento.
IMUL  reg, inmed              Multiplicación entera.
reg, r/m,inmed
INS  mem, DX                  Entrada de cadena desde el puerto DX.
INSB mem,DX                  Entrada de cadena de bytes desde el puerto DX.
INSW  mem DX                Entrada de cadena de palabras desde el puerto DX.
LEAVE                             Deja procedimiento.
OUTS DX, mem               Salida de cadena de bytes o palabras al puerto DX.
OUTSBDX,  mem             Salida de cadena de bytes al puerto DX.
OUTSW DX, mem            Salida de cadena de palabras al puerto DX.
POPA                              Saca todos los registros de la pila.
PUSH  inmed                   Introduce a la pila
PUSHA                            Introduce todos los registros.
RCL  r/m, inmed               Rotación a la izquierda con acarreo
RCR  r/m, inmed               Rotación a la derecha con acarreo.
ROL  r/m, inmed               Rotación a la izquierda.
ROR  r/m, inmed               Rotación a la derecha.
SAL  r/m, inmed               Desplazamiento aritmético a la izquierda.
SAR  r/m, inmed               Desplazamiento aritmético a la derecha.
SHL  r/m, inmed               Desplazamiento a la izquierda.
SHR  r/m, inmed               Desplazamiento a la derecha.

80286 (modo protegido)

ARPL  mem, reg               Ajusta petición de nivel de privilegio.
CLTS                               Limpia bandera de conmutación de tareas.
LAR reg, mem                  Carga derechos de acceso.
LGDT mem                      Carga la tabla de descriptores globales (8 bytes).
LIDT mem                        Carga tabla de descriptores de interrupciones (8 bytes).
LLDT mem                       Carga la tabla de descriptores locales.
LMSW mem                     Carga la palabra de estado.
LSL reg, mem                  Carga el límite del segmento.
LTR mem                         Carga registro de tareas.
SGDT mem                      Guarda la tabla de descriptores locales (8 bytes).
SIDT mem                       Guarda tabla de descriptores de interrupciones (8 bytes).
SMSW mem                    Guarda la palabra de estado.
STR mem                        Guarda registro de tareas.
VERR mem                      Verifica acceso de lectura.
VERW mem                     Verifica acceso de escritura.
80287
FSETPM                          Fija modo protegido.
FSTSWAX                       Almacena palabra de estado en AX (aguarda).
FNSTSWAX                     Almacena palabra de estado en AX (no aguarda).

Moviendo movimientos

MOV destino, origen
Esta función trata el intercambio entre registros, ya sean valores o direcciones. Pongamos un ejemplo:
Código: php
MOV EBX, 1
MOV EAX, EBX

Estamos enviando el valor 1 a EBX, y este pasaría a EAX. Recordemos que un registro está compuesto por 32 bit, pero en este caso únicamente utilizamos 4 bit, por lo que utilizaríamos únicamente los últimos 4 bit, es decir, BL y AL.
¿Pero no dijiste que podrías mover un valor o una dirección? Así es.

Supongamos por un momento, que tenemos una direccion en memoria, en el registro EBX, y queremos pasarlo a EAX... Hariamos lo mismo, ya que en el ejemplo anterior, pasamos la dirección de 1 a EAX. Si no queremos esto, podemos pasar únicamente el valor, en lugar de la dirección de la siguiente manera:
Código: php
MOV EAX, dowrd [EBX]

Le estaríamos indicando que pasaremos un valor de tamaño DWORD a EAX, y ese valor es el que estará presente en EBX.

Instrucción LEA

No, no te vamos a pedir que te pongas a leer... De momento. Recordando el caso de MOV... ¿Y si queremos un puntero? Fácil. La instrucción LEA se encarga de ello. Como vemos, la sintaxis es sencilla:
Código: php
LEA destino, origen

Supongamos que tenemos un valor almacenado en EDX, y queremos un offset en EAX, lo haríamos de la siguiente forma:
Código: php
LEA EDX, [EAX]

De esta forma, indicaríamos que pasaremos el offset (LEA) a EDX, residente en EAX

Instrucciones JMP y CALL

Estas instrucciones son las encargadas de desviar el programa a una zona determinada. La diferencia entre JMP y CALL, es que CALL realiza un salto a una subrutina con retorno, mientras que JMP realiza un salto dentro del segmento.
Su sintaxis es:
Código: php
JMP destino
CALL destino


Básicamente, la principal diferencia entre JMP y CALL, es que JMP ejecuta un salto a una línea de código, y CALL entra en una subrutina.

Comparaciones
JB o JNAE: Salta si CF está activada.
Objetivo: Saltar si la última comparación realizada con
números naturales da menor.

JG o JNLE: Salta si ZF es cero o si OF y SF son iguales.
Objetivo: Saltar si la última comparación realizada con
números enteros da mayor.

JL o JNGE: Saltar si SF es diferente a OF
Objetivo: Saltar si la última comparación realizada con
números enteros da menor.

JC: Saltar si CF está prendida
Objetivo: Saltar si hay acarreo

JO: Saltar si OF está prendido
Objetivo: Saltar si hay desbordamiento

JP: Saltar si PF está prendido
Objetivo: Saltar si hay paridad

JS: Saltar si SF está prendido
Objetivo: Saltar si es negativo

JNE o JNZ: Comportamiento inverso a JE o JZ

JNA o JBE: Comportamiento inverso a JA o JNBE

JNB o JAE: Comportamiento inverso a JB o JNAE

JNG o JLE: Comportamiento inverso a JG o JNLE

JNL o JGE: Comportamiento inverso a JL o JNGE

JNC: Comportamiento inverso a JC

JNO: Comportamiento inverso a JO

JNP o JPO: Comportamiento inverso a JP

JNS: Comportamiento inverso a JS


Algunas operaciones aritméticas

Suma:
Código: php

MOV EAX,10
MOV EDX,20
ADD EAX,EDX


Resta:
Código: php

MOV EAX,20
MOV EDX,10
SUB EAX,EDX


Multiplicación con signo:
Código: php

MOV EAX,10
MOV EDX,20
IMUL EAX,EDX


División sin signo:
Código: php

MOV AX,20
MOV BL,4
DIV BL


Ejemplo de una calculadora simple en NASM:
Citar
global main

extern printf
extern scanf
extern exit

segment .data
sVal1   DB   `Entero 1: \0`
sVal2   DB   `Entero 2: \0`
sTOTAL   DB   `Resultado: %i\n\0`
Ftoi   DB   `%i\0`
sMenu   DB   `@@@@@@@@@@@@@@@@@@@@@@\n@                    @\n@                    @\n@ Calculadora V1 ASM @\n@                    @\n@                    @\n@@@@@@@@@@@@@@@@@@@@@@\n\n1.- Suma\n2.- Resta\n3.- Multiplicación\n4.- División\n\nOpción:\n\0`
sMal   DB   `Opcion incorrecta\n\0`

segment .bss
NUM1   RESB   4
NUM2   RESB   4
Menu   RESB   4

segment .text
main:
   PUSH   EBP
   MOV   EBP,ESP
   SUB   ESP,4
   MOV   [ESP],dword sMenu
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword Menu
   CALL   scanf
   
   CMP   dword [Menu],4
   JA   optMal
   CMP   dword [Menu],1
   JE   Suma
   CMP   dword [Menu],2
   JE   Resta
   CMP   dword [Menu],3
   JE   Multip
   CMP   dword [Menu],4
   JE   Divis
   CALL   exit
optMal:
   MOV   [ESP],dword sMal
   CALL   printf
   JMP   main
Suma:
   MOV   [ESP],dword sVal1
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM1
   CALL   scanf

   MOV   [ESP],dword sVal2
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM2
   CALL   scanf

   MOV   EAX,dword [NUM1]
   MOV   EDX,dword [NUM2]
   ADD   EAX,EDX
   JMP   Resultado
Resta:
   MOV   [ESP],dword sVal1
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM1
   CALL   scanf

   MOV   [ESP],dword sVal2
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM2
   CALL   scanf

   MOV   EAX,dword [NUM1]
   MOV   EDX,dword [NUM2]
   SUB   EAX,EDX
   JMP   Resultado
Multip:
   MOV   [ESP],dword sVal1
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM1
   CALL   scanf

   MOV   [ESP],dword sVal2
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM2
   CALL   scanf

   MOV   EAX,dword [NUM1]
   MOV   EDX,dword [NUM2]
   IMUL   EAX,EDX
   JMP   Resultado
Divis:
   MOV   [ESP],dword sVal1
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM1
   CALL   scanf

   MOV   [ESP],dword sVal2
   CALL   printf
   MOV   [ESP],dword Ftoi
   MOV   [ESP+4],dword NUM2
   CALL   scanf

   MOV   AX,word [NUM1]
   MOV   DL,byte [NUM2]
   DIV   DL
   JMP   Resultado
Resultado:
   PUSH   EAX
   PUSH   sTOTAL
   CALL   printf
   LEAVE
   RET

Compilación en Windows:
Citar
nasm -f win32 -Wall --prefix _ Calc.ASM
gcc -o Calc.exe Calc.obj


Compilación en Linux:
Citar
nasm -f elf Calc.ASM
gcc -o Calc Calc.o

Fuente: Yo-Mismo (CodeSec.org)

Saludos
CPH: Cibergolen
Otros: Yo-Mismo

Visitame en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Después de un buen tiempo de espera, decidí entre cervezas continuar al manual que deje casi a medias...

Ahí va.

Índice:
1. Estructuras de control de proceso

  • Qué son
  • Ejemplo
  2. Subprocesos

  • La pila
  • Argumentos de pila
  • Llamada y retorno
  3. Sintaxis NASM

  • Funciones globales
  • Carga de funciones externas
  • Secciones
  • Etiquetas
  • Esqueleto de un programa
  4. NASM y GCC

  • Ejemplos
  • Ejercicio final
   
Estructuras de control de proceso
 
  Qué son:
  Las estructuras de control son procesos a alto nivel que realiza el compilador, con las que no contamos en ASM (A bajo nivel).
 
  Estas estructuras pueden ser bucles (While, For, ...), comparaciones (if's) y de ramificación.
 
  Ejemplo:
  Ejemplo de estos tres últimos tipos, en un comparador de cadenas:
 
Código: php
global main
   
  extern printf
   
  segment .data
  smal  DB         `Diferentes\0`
  sbien DB         `Iguales\0`
  Cadena1         DB         `aaaa\0`
  Cadena2         DB         `aaaa\0`
   
  segment .bss
  len1  resb         12
  len2  resb         12
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
           MOV         [ESP],dword Cadena1
           CALL         longitud
           MOV         dword[len1],EAX
           MOV         [ESP],dword Cadena2
           CALL         longitud
           MOV         dword[len2],EAX
           MOV         EAX,dword[len1]
           MOV         ECX,dword[len2]
           CMP         EAX,ECX
           JNE         Mal
           XOR         ECX,ECX
           MOV         EDX,dword[len1]
  Buclecmp:
           CMP         EDX,ECX
           JE         Bien
           MOV         AL,byte[Cadena1+ecx]
           MOV         BL,byte[Cadena2+ecx]
           CMP         AL,BL
           JNE         Mal
           INC         ECX
           JMP         Buclecmp
  Mal:
           PUSH      smal
           CALL       printf
           LEAVE
           RET
  Bien:
           PUSH      sbien
           CALL       printf
           LEAVE
           RET
  longitud:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           XOR         ECX,ECX
  BUCLE:
           LEA         EAX,[EBP+8]
           MOV         EAX,DWORD [EAX]
           MOV         BL,byte[EAX+ECX]
           CMP         BL,0
           JE         Retornar
           INC         ECX
           JMP         BUCLE
  Retornar:
           MOV         EAX,ECX
           LEAVE
           RET
 
Subprocesos
 
  Estamos por conocer más de cerca las instrucciones PUSH y POP.
 
  La pila es una lista de memoria en la que podemos manejarnos. Para que no se creen confusiones, se trata del Stack. Cuando realizamos PUSH estamos cargando datos a la pila, mientras que con POP lo descargamos. PUSH empuja un dato, mientras que POP se encarga del último (L.I.F.O)
 
  La instrucción PHSA empuja el contenido de los registros a la pila.
 
  Al realizar una llamada a un subproceso (Función) mediante CALL, éstos deben estar de acuerdo en el número y valor de parámetros que vamos a precisar (Argumentos).
 
  Los argumentos se almacenan en EBP+8, EBP+0xC y sucesivamente. Más allá de los parámetros recividos estaríamos tocando cosas que no deberíamos, y ya podrías imaginar el resultado.
 
  Un ejemplo de esto lo podemos ver en el ejemplo anterior, en la llamada al subproceso longitud (Función longitud)
Código: php
         MOV         [ESP],dword Cadena1 ;Cargar argumento, PUSH
           CALL         longitud
...........
Código: php
longitud:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           XOR         ECX,ECX
  BUCLE:
           LEA         EAX,[EBP+8]         ;Obtenemos direccion
           MOV         EAX,DWORD [EAX] ;Leemos puntero
           MOV         BL,byte[EAX+ECX]
           CMP         BL,0
           JE         Retornar
           INC         ECX
           JMP         BUCLE
  Retornar:
           MOV         EAX,ECX
           LEAVE
           RET
  El valor retornado siempre es almacenado en EAX. Realmente depende del programador, pero por regla general es así
 
 
Sintaxis NASM
    Declaraciones globales
 
  Funciones declaradas como globales, por ejemplo al usar C y  NASM
Código: php
Global main         ;Obligatorio
  Global funcion
Carga de funciones externas
 
  Cargar funciones externas.
Código: php
Extern printf
  Extern scanf
  Extern funcionpropia
  Secciones
 
  Son muchas, pero aquí van las más comunes.
Código: php
.BSS – Datos no inicializados (Variables)
  .DATA – Datos inicializados (Constantes)
  .TEXT – Texto
.CODE – Código
  Etiquetas
 
  Son labels que usamos para determinar el salto hacia otra línea de código (o dirección). Recuerda a GOTO, todo un clásico
 
Código: php
Bucle:
           CMP         EAX,0
           JNE         Bucle
           JMP         Fin
  Fin:
           RET
Esqueleto de un programa
 
Código: php
global main
   
  extern Funcionacargar
   
  segment .data
  constante         DB         `Valor\0`
   
  segment .bss
  variable         resb         1024         ;Longitud
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           LEAVE
           RET
   
NASM y GCC, Ejemplo de uso
    Dejo el análisis a vosotros para comprobar lo aprendido hasta ahora... Se que me quieres
    Subprocesos externos:
  b.asm:
Código: php
global main
   
  extern longitud
  extern printf
   
  segment .data
  ftoi   DB         `%i caracteres\0`
  Cadena         DB         `aaaaaaa\0`
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
   
           MOV         [ESP],dword Cadena
           CALL         longitud
           PUSH      EAX
           PUSH      ftoi
           CALL       printf
           LEAVE
           RET
  b.c:
Código: php
#include <stdio.h>
   
  int longitud(char *s1)
  {
      return strlen(s1);
  }
  Compilación:
Citarnasm -f win32 -Wall --prefix _ b.asm
  gcc -o b b.obj b.c
Ejercicio final:
  Realizar una calculadora utilizando GCC y NASM, utilizando estructuras de control, subprocesos, retornos y la pila
 
  Datos finales: Esperen la siguiente versión. Puntos flotantes, estructuras, matrices, ...
 
  Agradecimientos: Jep, Swash, 11Sep, Shadowbyte, Mr.Blood, ...
 
  Creado por: Yo-Mismo (Para No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y CPH)
 
  Las dudas las resuelvo por privado, no en el hilo (Mejor abrir tema nuevo.)
 
  Un saludo!
CPH: Cibergolen
Otros: Yo-Mismo

Visitame en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta (Creado a petición de un usuario)

Saludos!
CPH: Cibergolen
Otros: Yo-Mismo

Visitame en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Gracias por traerlo a Underc0de Cibergolean

Saludos.
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Gracias por traerlo a Underc0de Cibergolean

Saludos.

A ti por leerlo  :)

Un saludo!
CPH: Cibergolen
Otros: Yo-Mismo

Visitame en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta