	Octa-assembler 0.14
	Manual de usuario

	Octasm es un ensamblador para procesadores x86 requiere
un ordenador con procesador 80386+80387 (probado en un pentium)
y el sistema operativo dos o compatible, solo genera archivos binarios.
Los que no conozcan el juego de instrucciones de la familia x86 deberan
ir a la pagina web de intel y leerse los manuales, en este documento
solo se explican las instrucciones especiales de octasm.
_______________________________________________________________________
	Diferencias entre la version 0.15 y la 0.14
	Se a completado el conjunto de instrucciones ia32
	el punto '.' ahora se interpreta como una letra
	y se puede usar en los nombres.
	Tambien se ha cambiado la rutina 'atob' ahora la conversin
	de ascii a binario es mas rapida,precisa y se pueden separar
	los digitos usando la letra '_' ejemplo 0000_1001_0000_1000_b
_______________________________________________________________________
	Diferencias entre la version 0.14 y la 0.13
	Se han corregido algunos fallos.
	Comentarios multilinea poniendo ';;' al principio de la linea.
ejemplo:


;;       aqui empieza
	 el comentario
	 multilinea y
;;       aqui acaba

	La directiva 'define' ahora acepta parametros
ejemplo:

define REGS(tp1,tp2)  db >2->1 # db '%nb #1',tp1,tp2+10h*#0 #
REGS(reg_t,reg8,al,cl,dl,bl,ah,ch,dh,bh)

En este ejemplo se define 'REGS' que tiene los parametros
fijos 'tp1' y 'tp2' que seran reemplazados por 'reg_t' y 'reg8'
respectivamente y hay un parametro relativo '#1' que sucesivamente
se ira reemplazando por 'al','cl','dl' hasta procesar todos los
parametros tambien hay un contador '#0' que sucesivamente
se reemplazara  por '0','1','2' asi en el ejemplo previo el resultado
seria:

 db >2->1 # db '%nb al',reg_t,reg_8+10h*0 # db >2->1 # db '%nb cl',reg_t,reg_8+10h*1 #  etc...

	La directiva 'define' preprocesa texto, no instrucciones en ensamblador
asi que acepta qualquier tipo de parametro, si el parametro contiene
comas ',' o parentesis '()' debe ir entre parentesis y sin dejar espacios
despues de la coma ej: REGS((a,b),( p() ))
el numero de parametros fijos esta limitado a 16 y se definen con nombres
entre los parentesis. Los parametros relativos deben estar
entre #1 y #9 (#0 es el contador) y pueden ir pegados a cualquier cadena
en la definicion las demas letras carecen de significado, asi que se puede
reemplazar texto dentro de una cadena o formando un nombre compuesto.
En los archivos 'keyw.asm' y 'r' hay varios ejemplos del uso de define.
En la version actual la definicin completa debe de ocupar una sola linea
y no debe superar los 3kb tras el procesado.

_______________________________________________________________________
	Diferencias entre la version 0.13 y la 0.11

	Se han corregido algunos fallos. Los nombres de archivos ahora
son relativos a la posicion del archivo de codigo fuente en el que aparececen.
Los bloques '{ }' conservan la seccion actual
en la version 0.11 habia que escribir:
	code { data dd 0 } code
ahora basta con escribir:
	code { data dd 0 }

	Nuevas directivas
'define nombre texto' asigna el texto hasta el final de la linea
a la palabra nombre, cada vez que aparezca 'nombre' en el codigo
fuente, sera reemplazado por el texto, tambien se incluye el
caracter ';'.Las palabras se deben definir antes de ser usadas
y no se pueden volver a definir en el mismo directorio ni superiores.
ejemplo:
 {
 define uno 1
	{ #uno  ;error
	define dos 2
	}
	{
	#dos   ;valido ,esta en otro directorio
	}
 }
'enum incremento,nombre1,nombre2....,nombren' esta instruccion sirve
para definir variables y equivale a:
'#nombre1 rb incremento .... #nombren rb incremento'
el incremento debe ser un numero explicito, no valen expresiones.

ejemplo de como usar 'define' y 'enum' para simplificar la creacion
de subroutinas con paso de parametros a traves de la pila y variables
locales:

use16
prueba(1,2,3) ret

define LOCALS   pusha enter ->1,0 virtual org >1->2 # enum 2,  ;variables de 2 bytes se debe especificar al menos una
define PARAMS   # rb 20 enum 2,
define CODE     #RETURNS code
define RETURN   [bp+16]=ax leave popa retp RETURNS-20

#prueba{    ;se requiere '{' para evitar conflictos de nombres
	LOCALS x,y,z          ;variables locales
	PARAMS p1,p2,p3       ;parametros
	CODE
	w[bp+x]=10 w[bp+y]=20 w[bp+z]=30   ;inicializar variables locales
	ax=[bp+p1] add ax,[bp+y]           ;procesar
	RETURN                             ;se retorna el resultado en ax
					   ;los demas registros no cambian

       }

;la subroutina 'prueba',usando la antigua sintaxis
;equivale a lo que sigue:
	#prueba{
		virtual
		org -6 #x rb 2 #y rb 2 #z rb 2
		rb 20 #p1 rb 2 #p2 rb 2 #p3 rb 2
		code
		pusha enter 6,0
		w[bp+x]=10 w[bp+y]=20 w[bp+z]=30
		ax=[bp+p1] add ax,[bp+y]
		[bp+16]=ax leave popa retp 6
		}



	El program 'R'  ahora tambien muestra los registros del coprocesador
	Programas de ejemplo:
>octasm \r eax=1 fldpi          ;ejecuta las instrucciones y muestra el contenido de los registros
>octasm \off                    ;apaga el ordenador
>calc.bat 1+2*4.43              ;calcula la expresion numerica, que debe ir sin espacios.
_________________________________________________________________________


	Para los impacientes empezare poniendo algunos ejemplos y despues
se explicaran las instrucciones una a una con mas detalle.
lo que hay despues de '>' es lo que se debe escribir en la linea de comado.

ejemplo1:
>octasm dx="hello world$" ah=9 int 21h
ejemplo2:
>octasm org 100h file_out \hello.com dx="hello world$" ah=9 int 21h ret

Este programa imprime un mensaje en pantalla, en el primer ejemplo
el programa se ensambla en la memoria y se ejecuta
las instrucciones 'ret' y 'org' se aaden automaticamente.
en el segundo ejemplo se genera el archivo 'hello.com'.
para el siguiente ejemplo es preciso que el ordenador este en modo real
y con al menos 150kb de memoria libre

ejemplo3:
>octasm \octasm.asm

Se incluye el archivo en el codigo fuente, o sea que se
ensambla 'octasm.asm' generando los archivos 'octasm.com'
y 'octasm.sym' para ensamblar la version en espaol hay que
modificar la linea 119 en el archivo 'octasm.asm'
Se usan las mismas instrucciones en la linea
de comando y en los archivos con la diferencia de que los archivos
deben empezar todos con la secuencia 'LANG OCTASM,0.1'
Octasm distingue entre mayusculas y minusculas, las palabras clave
estan en minusculas y se usa el juego de caracteres latin1.
En general la sintaxis consiste en una instruccion seguida de
los parametros, el resultado de la operacion se almacena en el
primer parametro el caracter ';' indica que no hay mas instrucciones
hasta la siguiente linea , se usa para poner comentarios.
ej:   add ax,bx     ;coloca en ax el resultado sumar ax mas bx
las instrucciones que siempre llevan un solo parametro, se pueden
escribir con varios parametros, octasm generara varias instrucciones
pasando los parametros de izquierda a derecha.
ej: 'pop ax,5,[bx]'   equivale a 'pop ax pop 5 pop [bx]'
excepto en la instruccion 'push' que va de derecha a izquierda.
ej  'push ax,5,[bx]'  equivale a 'push [bx] push 5 push ax '
algunas instrucciones se pueden escribir usando una sintaxis alternativa
ejemplo:        equivale a:
eax=0           mov eax,0      ;nota: puede que lo cambie por 'xor eax,eax'
			       ;recomiendo considerar el estado de eflags
			       ;como indefinido en este tipo de instrucciones
ax=[bx+2]       mov ax,[bx+2]
ax=bx+2         lea ax,[bx+2]
es=ss           push ss pop es
es=5            push 5  pop es
d[bx]=[esp+4]   push d[esp+4] pop d[bx]
eax=ah          movzx eax,ah
f1()            call f1         ;sin espacios entre los parentesis
f1( 1,2,3 )     push 1,2,3 call f1

cuando tenga tiempo ire aadiendo mas operadores como: '+=' '-='
pero de momento solo funciona  '='.

Nombres:
	En octasm se le puede dar nombre a los
numeros ,direcciones de memoria y directorios
un nombre puede representar a la vez a un directorio y a un
numero, el anidamiento de directorios esta limitado a 16
los nombres solo se pueden definir una vez y en el directorio
al que pertenecen, pero se puede definir el mismo nombre
en cada directorio, pues el nombre completo seria distinto.
ejemplos:
n1=10           ;ahora escribir 'ax=n1' es lo mismo que escribir 'ax=10'
#l1             ;lo mismo que 'l1:' en otros ensambladores
		;este nombre ahora contendra el puntero de instruccion
#               ;direccion anonima
{               ;directorio anonimo ,los nombres contenidos en este directorio
		;solo son accesibles dentro del directorio
		;permite ahorrar memoria en el proceso de ensamblado
}               ;cerrar directorio
d1{             ;definicion de un directorio llamado 'd1'
  #l1           ;el nombre completo seria d1\l1
  #l2{          ;definicion de una direccion y de un directorio
     #l2 { }    ;direccion + directorio anonimo
     l1()       ;si l1 no se define en el directorio actual
		;se buscara en el directorio padre
     d1=5       ;'d1\l2\d1' no confundir con 'd1'
     ax=d1      ;ax=5
     }
  ax=d1         ;ax=2
  ax=l2\d1      ;ax=5
  l2\l2()       ;fuera del directorio 'l2' se debe escribir el nombre completo
  jmp <1        ;incorrecto porque no se ha definido '#' en este directorio
  jmp >1        ;salto incondiciona hacia la proxima direccion anonima
  #
  }
d1=2            ;d1 pertenece al directorio raiz y solo se puede definir
		;en el mismo directorio
jmp <1          ;salto incondiciona hacia direccion anonima anterior
		;en el mismo directorio

Numeros:
los hexadecimales deben acabar en 'h' y empezar por '0' si el
primer digito es una letra ej:  43h 0123h
los binarios deben acabar en 'b' ej: 1101b
los numeros enteros estan limitados a 4gb-1
los numeros en coma flotante deben llevar un punto
y escribirse sin espacios
      ej:  1.0e34   correcto
	   1.0 e34  incorrecto
	   1e34     incorrecto


Archivos:
	el nombre de un archivo es lo que hay entre '\' y ' ' todos los demas
caracteres son validos incluido ';'.
ejemplos:
el archivo:             se escribe:
test.asm                \test.asm
\test.asm               \\test.asm
c:test.asm              \c:test.asm
un archivo puede ser usado como parametro, octasm abre el archivo
en modo lectura/escritura y si no existe se crea
y se ensambla la instruccion con el handler correspondiente, aunque
esto solo es util si el programa se ensambla en memoria para ser
ejecutado de inmediato
ej:
eax=\file.pcx          ;equivale a 'eax=16' suponiendo que 16 sea el handler
		       ;retornado por el sistema operativo
eax=\file.pcx          ;equivaldria a 'eax=17' el archivo se abre de nuevo

Cadenas de texto:
	las comillas se usan para delimitar cadenas de texto
la comilla simple indica que la cadena debe ser copiada en la instruccion
y la comilla doble almacena la cadena en otra parte y retorna un puntero
ej:
		eax='A'+1 ret
equivale a      eax=65+1 ret
		eax="hello world" ret
equivale a      eax=label ret #label db 'hello world'
eax='hello word'    ;es incorrecto porque la cadena tiene mas de 32bits
dentro de una cadena se pueden usar dos comandos:
%nb       retorna el numero de bytes hasta el final de la cadena 255 max
	  debe ir seguido de un espacio.
%0-255    para codificar caracteres no imprimibles
	  el espacio que hay despues del comando es suprimido.

ejemplo: db '%nb %13%10 %nb '     equivale a :  db 2,13,10,0

Expresiones aritmeticas:
	octasm utiliza el coprocesador matematico para realizar los
calculos, es importante saber como se hace el redondeo:
en octasm 3/2=2   en otros ensambladores 3/2=1
porque 3/2=1.5 y 1.5 se redondea a 2
en las expresiones aritmeticas se pueden usar toda clase de numeros
ej:   eax=[ebx*(3.14e-1+1)+'A']    se ensamblaria como eax=[ebx+65]

direcciones anonimas '#':
	se referencian usando '<1-7' o '>1-8'
ejemplo:  jc >1 # jc <1
bucles anidados:
	{ ecx=20
	# push ecx
		{ ecx=10 # f1() loop <1}
	pop ecx loop <1
	}
	sirven para no tener que pensar nombres y para no sobrecargar
	la tabla de simbolos.

Punteros:
	Los punteros son direcciones de memoria escritas entre
	corchetes ej:'[bx+5]'
	el tamao del operando se especifica antes del puntero
	ejemplo: 'd[bx+5]'
	el tamao del offset no se indica, octasm usara offsets
	de 32 bits en programas de 16 bits cuando sea necesario.
	ejemplo: '[12]'  ;offset de 8 bits
		 '[1234]' ;offset de 16 bits en programas de 16 bits
			  ;y de 32bits en programas de 32 bits
		'[123456]';offset de 32 bits
	a diferencia de otros ensambladores , no se usa ':' con
	los segmentos ej: '[ebx+es+5]' 'd[cs+128]'


Instrucciones 'call' y 'jmp' :
	Se puede llamar a una subrutina con parentesis cuando
se usa con nombres ej:  f1() f2( ax,bx )
los parametros se pasan al stack de derecha a izquierda
en los demas casos se debe usar 'call'
ej:   call >1 ret  #
      call far [bx]   ;far indica que se usa un offset y un segmento
      call far d[bx]  ;direccion de 32+16bits
      jmp far w[56]   ;direccion de 16+16 bits
      call ax
      jmp 1,2        ; 2:1  se escribe primero el offset y despues el segmento
      call d 1,8     ; offset de 32bits + segmento
Directivas:

b,w,d,q  indican el tamao del operando que es respectivamente  1,2,4,8
	 debido a un error que solucionare mas adelante
	 se debe escribir 'push w(4+5)' en lugar de 'push w 4+5'

far      se usa con 'jmp' y 'call' para indicar una variable que contiene
	 un segmento y un offset

db,dw,dd,dq  para inicializar numeros enteros
	      de 1,2,4,8 bytes
	      'db' ademas puede contener cadenas

float,double,dt   numeros en formato de coma flotante de 4,8 y 10 bytes

rb numero         reserva espacio rellenando con ceros

section numero    el numero de seccion debe de estar entre 0 y 15
		  una seccion es una zona de la memoria o de un
		  archivo, donde se colocan un conjunto de
		  datos o instrucciones.
		  por defecto se inicializan 4 secciones con distintas
		  propiedades:
 code      section 0
		  cuando se ensambla en memoria, se coloca en el
		  mismo segmento de codigo usado por octasm, que ocupa
		  20kb por lo que el tamao maximo es de 44 kb
		  la instruccion 'align' usa la instruccion 'nop' para
		  alinear el codigo
 data      section 2
		  el alineamiento se hace con ceros
		  cuando se ensambla en memoria esta seccion
		  se coloca en el segmento de datos que puede ser superior
		  a 64kb
 text      section 1
		  igual que data pero en esta seccion se colocan
		  las cadenas con comillas dobles.
 virtual   section 3
		  esta seccion no genera codigo , solo sirve para calcular
		  direcciones de memoria, algo parecido a lo que hace
		  '?' en otros ensambladores.
  cuando se selecciona por vez primera una seccion,esta hereda las
  propiedades de la seccion actual ejemplos:
  code    section 5     ;ahora la seccion 5 es de codigo
  text    section 5     ;ahora code y text representan la misma seccion
  data                  ;seccion 2
  text                  ;seccion 5
  section 4             ;seccion 4 que al igual que la 5 es codigo
  data                  ;seccion 2
  text                  ;seccion 4
		   las secciones se ensamblan por orden ascendente
		   y se colocan en los archivos una detras de otra
		   cuando se ensambla en memoria las secciones no
		   son contiguas.
		   se pueden ensamblar algunas secciones en memoria
		   y otras en un archivo.

org numero     indica la direccion de memoria en la que se colocaran
	       los datos/instrucciones
	       el valor por defecto es cero
	       cuando se ensambla en memoria no hace falta usar esta
	       directiva
	       ej: org 100h
		   inicio=5000
		   #
		   org inicio+45
		   org <1            ;org 100h


align numero   rellena con ceros o 'nop' hasta que el puntero de instruccion
	       sea multiplo del numero
	       ej:
	       align 4
	       align 7c00h+510

include archivo,posicion,numero de bytes a copiar
	       para incluir un archivo de codigo fuente basta con
	       escribir el nombre del archivo, para copiar archivos
	       binarios se usa 'include' si no se indica el numero
	       de bytes a copiar el archivo se copiara hata el final
	       si no se indica la posicion, el archivo se copia desde
	       el principio
     ejemplos:
  >octasm file_out \ab include \a include \b
    este comando hace lo mismo que la instruccion 'copy /b' del dos
    copiando los archivos 'a' y 'b' en 'ab'
    con la siguiente instruccion se puede copiar una imagen en el programa
    saltandose la cabecera de 54 bytes
    ej:  include \img.bmp,54

file_out archivo
	 Especifica el archivo en el que se escribira el codigo
	 se puede usar un archivo en cada seccion si varias secciones
	 usan el mismo archivo ,solo se indica en la primera.
	 ejemplos:
	 section 0                      ;se ensamblara en memoria
	 section 1                      ;se ensamblara en memoria
	 section 2  file_out \prog.com  ;se ensamblara 'prog.com'
	 section 3                      ;virtual, no se genera codigo
	 section 4  file_out \prog.dat  ;se ensamblara 'prog.dat'
	 section 5                      ;se ensamblara 'prog.dat'
					;etc...

file_sym archivo
	Especifica el archivo en el que se escribira la tabla
	de simbolos que contiene todos los simbolos del programa
	y su valor correspondiente.
	Esta instruccion solo se puede usar una vez en todo el programa.
	Sirve para hacer compilacion incremental,overlays
	y para depuracion simbolica.
	Cuando se ensambla en memoria, el programa funciona como si
	fuera un overlay de octasm, y se puede usar el codigo
	de octasm incluyendo la tabla de simbolos.
	ejemplo:
	lib{ \octasm.sym } ;'octasm.sym' se genera ensamblando 'octasm'
	ecx=40 lib\malloc();se usa el directorio 'lib' para evitar
			   ;conflictos de nombres
	Para hacer overlays se puede usar una seccion para cada overlay
	ejemplo:
	;secciones 0-4 para el programa base
	file_out \base.com
	\base.asm #
	ovl1{ code section 5  file_out \ovl1.bin \ovl1.asm }
	org <1 ;direccion en que se cargara el programa
	ovl2{ code section 6  file_out \ovl2.bin \ovl2.asm }
	org <1 ;etc...
	La compilacion incremental puede servir para ensamblar programas
	muy grandes usando menos memoria y menos tiempo.
	primero se ensambla una parte del programa generando un archivo
	binario y una tabla de simbolos que se incluiran en la siquiente
	parte del programa,esto tiene el inconveniente de que la primera
	parte del programa no puede contener referencias a otras partes
	del programa.

	las instrucciones 'usexx_xx' se deben usar solo una vez en cada
	seccion y antes de otras instrucciones, para mezclar codigo
	de 16 y 32 bits en una misma seccion hay que usar los prefijos:
	db 66h  ; datos de 32bits
	db 67h  ; punteros de 32bits
use16   programa de 16 bits,las instrucciones de 32 bits se codificaran
	usando prefijos.
use32   programa de 32 bits
use16_32  algunas instrucciones usan parametros por defecto (movsb)
	  con esta directiva se indica que algunas instrucciones usaran
	  punteros y datos de 32 bits ,esta es la opcion por defecto
	  es igual que use16 excepto que las siguientes instrucciones
	  se codifican como instrucciones de 32 bits:
	  lods  (lodsb lodsw lodsd) ;usara los registros esi,edi
	  movs stos scas cmps ins outs
	  loop   ;el contador sera ecx

Ensamblado en memoria
	una de las caracteristicas especiales de 'octasm' es que permite
	ejecutar directamente el codigo fuente sin necesidad de tener
	ejecutables en el disco, estos programas funcionan como si fueran
	overlays de octasm, el codigo se coloca en el mismo segmento de
	codigo a continuacion del de octasm y los datos en el segmento
	de datos (ds=cs+1000h).
	Cuando el ordenador esta en modo
	real octasm cambia el limite de los segmetos (es,ds,ss,fs,gs) a 4gb
	y para acceder a los datos del programa es preciso utilizar
	punteros de 32 bits y el programa se debe terminar usando
	la instruccion 'ret' para que octasm pueda retornar al sistema
	operativo la memoria extendida.
	cuando el ordenador no esta en modo real octasm solo usa
	64kb y los datos del programa se pueden direccionar con punteros
	de 16 bits pero solo se podran ensamblar programas pequeos.


Ensamblado en archivos
	Como octasm por defecto se inicializa con: 'org 0 use16_32'
	al ensamblar un programa en formato '.com' hay que incluir
	estas instrucciones:  org 100h use16
	las instrucciones como:  eax=\archivo
	carecen de sentido cuando se ensambla a un archivo y no se
	deben usar.

R       el archivo 'R' contiene un programa en ensamblador que permite
	ejecutar unas pocas instrucciones y ver el contenido de los registros
	los registros se guardan en el archivo 'regs.dat'.
	uso: >octasm \r instrucciones
	el registro esp no se debe cambiar.
	ejemplos:
>octasm \r eax=1 ecx=4
>octasm \r shl eax,cl
>octasm \r add eax,ecx
	ahora eax contentra el valor 20
________________________________________________________
	Problemas
	Hay algunos errores en octasm que requieren cambios importantes
asi que seran corregidos mas tarde.
	eax=dir dir\v1()  ;octasm se cuelga si es la primera vez que 'v1' se usa
	dir2(dir2\v1)     ;idem
la solucion es separar mediante cambio de linea:
	eax=dir
	dir\v1()
o insertando otra palabra en medio:
	push dir2\v1 call dir2
_______________________________________________________
para mas informacion visite mi pagina web:
http://octavio.vega.fernandez.googlepages.com/octaos

