

; El punto y coma indica que el resto de la l{nea es un comentario.

; El programa debe empezar a ensamblarse (generar su código) a partir
; de cierta direcci{on de memoria que se indica con un asterisco,
; un signo de igual y la dirección en cuestión.

		*= 0x100

; En esta máquina virtual hay solamente 64 Kbytes de memoria RAM.
; Las direcciones constan de hasta 4 dígitos hexadecimales.

; Cada variable global se ensambla dando su nombre y por medio de
; pseudoinstrucciones se establece su valor inicial y su tamaño en
; bytes
	
@masa:		word 54
@vel:		word 25
@letrero:	byte "hola, mundo¬\n"

; debemos notar que los nombres de las variables se están escribiendo
; con una arroba al inicio, esto se hace para evitar que los nombres de
; las variables se confundan con nombres de instrcciones o de pseudo-
; instrucciones.   Por ejemplo, una variable no puede llamarse word,
; ni ppuede llamarse  lda porque estos nombres están reservados por
; el lenguaje ensamblador.

; Hemos dado cada nombre y queda definido al escribir después
; de él dos puntos.  El nombre es realmente un APUNTADOR o dirección
; de memoria. 
; Como hemos empezado a ensamblar en la dirección 0x100, entonces
; @masa queda hubicada en la direción 0x100 y es de tipo word que son
; enteros de 16 bits y su valor inicial es 0.  
; @vel también es un entero de 16 bits y su valor inicial es 25 y está
; ubicada en la dirección de memoria 0x102.
; @letrero es la dirección de memoria de un arreglo de caracteres que
; termina en 0.  En este caso la "cadena" dice "hola, mundo\n" y ocupa
; 13 bytes de espacio en memoria.  Nòtese que \n es un solo carácter (10)
; y que toda cadena termina en el carácter 0.

	word @masa, @vel, @letrero
 
; El programa debe tener un punto de inicio, generalmente una función
; y debe tener también un lugar donde va a estar la pila.   Hay
; direcciones importantes para la pila, su base que la establece 
; el registro BP y su tope que lo establece el registro SP.
; al terminar un programa debe establecerse el punto de entrada 
; del programa y la base de la pila mediante la pseudoinsrucción end
; Después de end el ensamblador deja de hacer su función.

;	end  @main, pila

; Una función debe tener un nombre y debe establecerse un marco de
; referencia de la pila.  

@main:
		PSH BP		; se manda a la pila en BP
		LBP SP		; se carga el BP con el valor de SP

; Al terminar la función, el valor de retorno (si lo hay) regresa
; en el acumulador A y debe de deshacerse el marco de referencia.

		LSP BP		; Se vacia la pila, cargando el valor de BP en SP
		POP BP		; desempilando el antiguo BP
		RTN			; Instrucción de retorno,  desempila el PC de donde
					; fue invocada la función.

; Instrucciones y modo de acceso a la información.
; Las instrucciones en ensamblador son nombres de 3 letras generalmente.
; son abreviaturas o mnemónicos de las acciones que ejecutan.

; Una de las más importantes es LDA, que carga información en el acumulador A.

; Modo inmediato
		LDA #5			; Cargar el acumulador con el valor dado.
		LDA #0x3322 
		LDA #5+4		; esa pequeña expresion la evalúa el ensamblador 
						; no el procesador.

; Modo directo			Carga información desde la memoria.
		LDA [@masa]		; esta instrucción carga en A el contenido de la
						; variable global @masa.

; Modo indirecto B		Carga información desde la direcciòn de memoria
;						a la que señale el registro B.
		LDA [B]			; es como usar a B como ìndice de la memoria.

; Modo relativo a la base de la pila.  Se carga en el acumulador el contenido
;						de la localidad de memoria cuya dirección resulta de
;						la suma/resta del registro BP y un valor dado.
		LDA [BP+6]		

; Modo inherente
; Hay otras instrucciones que tienen algunos otros modos de establecer sus
; parámetros.  Por ejemplo, las operaciones aritméticas siempre actúan
; sobre el valor en el deja en A la suma de tope_de_la_pila + A.tope de la pila (descargándolo) y el acumulador A.

		ADD			;  deja en A el tope_de_la_pila + A.
		SUB			;  deja en A el tope_de_la_pila - A.
		MUL			;  deja en A el tope_de_la_pila * A.
		DIV			;  deja en A el tope_de_la_pila / A.
		MOD			;  deja en A el tope_de_la_pila % A.

		AND			; deja en A el tope_de_la_pila & A (bit por bit).
		OR			; deja en A el tope_de_la_pila | A (bit por bit).
		XOR			; deja en A el tope_de_la_pila ^ A (bit por bit).
		SHR			; deja en A el tope_de_la_pila >> A 
		SHL			; deja en A el tope_de_la_pila << A
		CMP			; Hace la resta tope_de_la_pila -A pero no guarda resultado

; hay instrucciones que sólo usan al acumulador
		NOT			; deja en A la negación bit por bit de A, es decir ~A
		NEG			; deja en A el inverso aditivo de A, es decir -A
		TST			; deja en A, 0 si el valor de A era 0; 1 si no lo era.
		
; Modo registro
; Hay instrucciones que operan sobre registros.
		LSP BP		; Carga en SP el valor de BP
		LBP SP		; Carga en BP el valor de SP
		CLR A		; Carga un 0 en el acumulador A

; Acceso a la pila.
; La instrucción PSH mete información a la pila.
		PSH A		; mete el valor de A a la pila.
		PSH B		; mete el valor de B a la pila.
		PSH BP		; mete el valor de BP a la pila.

; La instrucción POP saca información de la pila.
		POP A		; sacar de la pila un entero y guardarlo en A.		
		POP B		; sacar de la pila un entero y guardarlo en B.		
		POP BP		; sacar de la pila un entero y guardarlo en BP.		

; Saltos.
; Hay instrucciones que permiten hacer saltos en el programa.
; Un salto es cargar en el registro PC una direcciòn nueva.
; Recordemos que SP contiene la direcciòn de la instrucción
; que va a ejecutarse (no la que se está ejecutando)

; los saltos se establecen mediante direcciones a las que se 
; quiere saltar.  La dirección generalmente se establece mediante
; una etiqueta.

@1:		LDA #5
		PSH A
		LDA #4
		ADD
		JMP @1

; Hay saltos que se ejecutan si una condición se cumple.
;	comparaciones de igualdad
; 		JEQ @destino	; el salto se ejecuta si la bandera Z==1
;						; la última operación dio como resultado 0	
; 		JNE @destino	; el salto se ejecuta si la bandera Z==0
;						; la última operación dio resultado distinto de 0	
;	comparaciones de orden
; 		JGT @destino	; el salto se ejecuta si el resltado es positivo
;						; Z==0 &&N==0 && o==0 || N==1 && o==1
; 		JLT @destino	; el salto se ejecuta si el resltado es negativo
;						; Z==0 && (N==1 && o==0 || N==0 && o==1)
; 		JGE @destino	; el salto se ejecuta si el resltado es positivo o cero
;						; N==0 && o==0 || N==1 && o==1
; 		JLE @destino	; el salto se ejecuta si el resltado es negativo o cero
;						; N==1 && o==0 || N==0 && o==1

; Instrucciones de servicios.
		IRQ rd_int		; lee un entero del teclado y lo guarda en A
		IRQ pr_int		; escribe el contenido del acumulador A en la pantalla
		IRQ pr_str		; Supone que en el registro B hay un apuntador a una
						; cadena de caracteres y dicha cadena se imprime

