cursos:ensamblador:ensambladores

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
cursos:ensamblador:ensambladores [16-01-2024 07:33] – [Programas ensambladores] sromerocursos:ensamblador:ensambladores [24-01-2024 08:01] (actual) sromero
Línea 15: Línea 15:
 Aunque estos 3 ensambladores comprenden los **nmemónicos** del Z80 (las instrucciones que hemos estado viendo en los anteriores capítulos), hay algunas pequeñas diferencias entre ellos. Por ejemplo (sólo citando dos de ellas para ver de qué tipo de diferencias hablamos): Aunque estos 3 ensambladores comprenden los **nmemónicos** del Z80 (las instrucciones que hemos estado viendo en los anteriores capítulos), hay algunas pequeñas diferencias entre ellos. Por ejemplo (sólo citando dos de ellas para ver de qué tipo de diferencias hablamos):
  
-   * pasmo y sjasmplus usan el nmenónico ''EX AFAF<nowiki>'</nowiki>'' mientras que z80asm también puede utilizar ''EX AFAF'' sin la comilla tras F.+   * pasmo y sjasmplus usan el nmenónico ''ex afaf<nowiki>'</nowiki>'' mientras que z80asm también puede utilizar ''ex afaf'' sin la comilla tras F.
  
-   * sjasmplus soporta "Fake instructions" (expande instrucciones que no existen como ''LD HLBC'' en ''LD HB'' + ''LD LC'', por ejemplo) mientras que pasmo y z80asm no.sj+   * sjasmplus soporta "Fake instructions" (expande instrucciones que no existen como ''ld hlbc'' en ''ld hb'' + ''ld lc'', por ejemplo) mientras que pasmo y z80asm no.sj
  
 Pero la mayor incompatibilidad viene en las **directivas** del lenguaje ensamblador, es decir, en esas palabras clave que incluímos en el código y que no forman parte del programa final sino que son usadas por el ensamblador para generar el binario resultante. Son ejemplos de directivas ''ORG'', ''EQU'', ''END'', ''DB''/''DEFB'' o ''INCLUDE'', por citar algunas de las que ya hemos visto, y que sí que funcionan de la misma forma en los diferentes ensambladores. Pero la mayor incompatibilidad viene en las **directivas** del lenguaje ensamblador, es decir, en esas palabras clave que incluímos en el código y que no forman parte del programa final sino que son usadas por el ensamblador para generar el binario resultante. Son ejemplos de directivas ''ORG'', ''EQU'', ''END'', ''DB''/''DEFB'' o ''INCLUDE'', por citar algunas de las que ya hemos visto, y que sí que funcionan de la misma forma en los diferentes ensambladores.
Línea 33: Línea 33:
 Los siguientes 3 apartados mostrarán lo siguiente: Los siguientes 3 apartados mostrarán lo siguiente:
  
-   * **Directivas comunes**: aquellas directivas de ensamblador básicas, presentes en prácticamente todos los programa ensambladores, y cuyo uso no suele variar entre ellos (tienen el mismo formato y se utilizan de la misma forma y con los mismos parámetros), como ''ORG'', ''EQU'', ''DB/DEFB/DW/DEFW'', ''INCLUDE'', etc.+\\  
 +   * **Directivas comunes entre ensambladores**: aquellas directivas de ensamblador básicas, presentes en prácticamente todos los programa ensambladores, y cuyo uso no suele variar entre ellos (tienen el mismo formato y se utilizan de la misma forma y con los mismos parámetros), como ''ORG'', ''EQU'', ''DB/DEFB/DW/DEFW'', ''INCLUDE'', etc.
        
    * **Directivas propias de pasmo**: directivas y peculiaridades de pasmo. Hablaremos de cómo se ensamblan programas en pamo y de algunas directivas que se utilizan en pasmo de diferente forma que en otros ensambladores, como las etiquetas locales.    * **Directivas propias de pasmo**: directivas y peculiaridades de pasmo. Hablaremos de cómo se ensamblan programas en pamo y de algunas directivas que se utilizan en pasmo de diferente forma que en otros ensambladores, como las etiquetas locales.
Línea 47: Línea 48:
  
 \\  \\ 
-===== Directivas comunes =====+===== Directivas comunes entre ensambladores =====
  
-Las siguientes directivas son comunes a los diferentes ensambladores, y se utilizan de una forma muy similar.+Las siguientes directivas son comunes a los diferentes ensambladores, y se utilizan de una forma muy similar. Se suelen indentar 4 espacios desde el inicio de la línea por legibilidad, y porque sjasmplus lo requiere para muchos de ellos (mientras que pasmo no).
  
 Ya hemos utilizado algunas de ellas en programas de ejemplo, y otras las utilizaremos en posteriores capítulos. Ya hemos utilizado algunas de ellas en programas de ejemplo, y otras las utilizaremos en posteriores capítulos.
Línea 65: Línea 66:
     ORG 35000     ORG 35000
  
-    CALL Inicializar+    call Inicializar
          
 menu: menu:
-    CALL Inicializar_Variables_Juego +    call Inicializar_Variables_Juego 
-    CALL Menu_Principal+    call Menu_Principal
  
 main: main:
-    CALL Juego +    call Juego 
-    CALL GameOver +    call GameOver 
-    JR menu+    jr menu
          
     INCLUDE "menu.asm"     INCLUDE "menu.asm"
Línea 117: Línea 118:
  
 \\  \\ 
-===== pasmo =====+===== Directivas específicas de pasmo =====
  
 \\  \\ 
Línea 142: Línea 143:
  
                         ORG 33500                         ORG 33500
-  82DC   CD 0DAF            CALL CLS+  82DC   CD 0DAF            call CLS
  
-  82DF   06 FF              LD B, 255+  82DF   06 FF              ld b, 255
                         bucle:                         bucle:
-  82E1   C5                 PUSH BC +  82E1   C5                 push bc 
-  82E2   48                 LD CB +  82E2   48                 ld cb 
-  82E3   06 00              LD B, 0 +  82E3   06 00              ld b, 0 
-  82E5   CD 82F1            CALL PrintNum +  82E5   CD 82F1            call PrintNum 
-  82E8   C1                 POP BC +  82E8   C1                 pop bc 
-  82E9   CD 8304            CALL PrintSpace+  82E9   CD 8304            call PrintSpace
  
-  82EC   10 F3              DJNZ bucle+  82EC   10 F3              djnz bucle
  
-  82EE   C9                 RET+  82EE   C9                 ret
  
   82EF   FFFF           variable      DEFW 65535   82EF   FFFF           variable      DEFW 65535
Línea 186: Línea 187:
 _loop: _loop:
     ...     ...
-    JR NZ, _loop +    jr nz, _loop 
-    RET+    ret
  
 Rutina2: Rutina2:
Línea 193: Línea 194:
 _loop: _loop:
     ...     ...
-    JR Z, _loop +    jr z, _loop 
-    RET+    ret
 </code> </code>
 \\  \\ 
Línea 220: Línea 221:
 \\  \\ 
 <code z80> <code z80>
-    LD B, 8                 ; 8 scanlines+    ld b, 8                 ; 8 scanlines
  
 drawsp8x8_loopLD: drawsp8x8_loopLD:
-    LD A, (DE)              ; Tomamos el dato del sprite +    ld a, (de)              ; Tomamos el dato del sprite 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite +    inc de                  ; Incrementamos puntero en sprite 
-    INC H                   ; Incrementamos puntero en pantalla (scanline+=1) +    inc h                   ; Incrementamos puntero en pantalla (scanline+=1) 
-    DJNZ drawsp8x8_loopLD+    djnz drawsp8x8_loopLD
 </code> </code>
 \\  \\ 
Línea 235: Línea 236:
 \\  \\ 
 <code z80> <code z80>
-    LD A, (DE)              ; Tomamos el dato del sprite (scanline 0) +    ld a, (de)              ; Tomamos el dato del sprite (scanline 0) 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite +    inc de                  ; Incrementamos puntero en sprite 
-    INC H                   ; Incrementamos puntero en pantalla (scanline+=1)+    inc h                   ; Incrementamos puntero en pantalla (scanline+=1)
  
-    LD A, (DE)              ; Siguiente scanline (scanline 1) +    ld a, (de)              ; Siguiente scanline (scanline 1) 
-    LD (HL), A +    ld (hl), a 
-    INC DE +    inc de 
-    INC H+    inc h
  
-    LD A, (DE)              ; Siguiente scanline (scanline 2) +    ld a, (de)              ; Siguiente scanline (scanline 2) 
-    LD (HL), A +    ld (hl), a 
-    INC DE +    inc de 
-    INC H+    inc h
  
     (...)                   ; Y así 8 veces     (...)                   ; Y así 8 veces
  
-    LD A, (DE)              ; Siguiente scanline (scanline 7) +    ld a, (de)              ; Siguiente scanline (scanline 7) 
-    LD (HL), A +    ld (hl), a 
-    INC DE +    inc de 
-    INC H                   ; Esto podríamos eliminarlo+    inc h                   ; Esto podríamos eliminarlo
 </code> </code>
 \\  \\ 
Línea 266: Línea 267:
 <code z80> <code z80>
     REPT 8     REPT 8
-    LD A, (DE)              ; Tomamos el dato del sprite (scanlines 0-6) +    ld a, (de)              ; Tomamos el dato del sprite (scanlines 0-6) 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite +    inc de                  ; Incrementamos puntero en sprite 
-    INC H                   ; Incrementamos puntero en pantalla (scanline+=1)+    inc h                   ; Incrementamos puntero en pantalla (scanline+=1)
     ENDM     ENDM
 </code> </code>
Línea 279: Línea 280:
 <code z80> <code z80>
     REPT 7     REPT 7
-    LD A, (DE)              ; Tomamos el dato del sprite (scanline 0-6) +    ld a, (de)              ; Tomamos el dato del sprite (scanline 0-6) 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite +    inc de                  ; Incrementamos puntero en sprite 
-    INC H                   ; Incrementamos puntero en pantalla (scanline+=1)+    inc h                   ; Incrementamos puntero en pantalla (scanline+=1)
     ENDM     ENDM
  
-    LD A, (DE)              ; Ultimo scanline (scanline 7) +    ld a, (de)              ; Ultimo scanline (scanline 7) 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite+    inc de                  ; Incrementamos puntero en sprite
 </code> </code>
 \\  \\ 
Línea 295: Línea 296:
  
 \\  \\ 
-===== sjasmplus =====+===== Directivas específicas de sjasmplus =====
  
 ==== Generar BINs, TAPs y SNAs con sjasmplus ==== ==== Generar BINs, TAPs y SNAs con sjasmplus ====
Línea 321: Línea 322:
     ORG 35000     ORG 35000
  
-BORDCR EQU $5C48    ; Spectrum's system variable address: BORDER colour+BORDCR EQU $5c48    ; Spectrum's system variable address: BORDER colour
  
 ;---------------------------------------------------------------------- ;----------------------------------------------------------------------
Línea 431: Línea 432:
 .loop: .loop:
     ...     ...
-    JR NZ, .loop +    jr nz, .loop 
-    RET+    ret
  
 Rutina2: Rutina2:
Línea 438: Línea 439:
 .loop: .loop:
     ...     ...
-    JR C, .loop+    jr c, .loop
 .loop2: .loop2:
-    JR Z, .loop2 +    jr z, .loop2 
-    RET+    ret
 </code> </code>
  
Línea 452: Línea 453:
 <code z80> <code z80>
     REPT 8     REPT 8
-    LD A, (DE)              ; Tomamos el dato del sprite (scanlines 0-6) +    ld a, (de)              ; Tomamos el dato del sprite (scanlines 0-6) 
-    LD (HL),              ; Establecemos el valor en videomemoria +    ld (hl),              ; Establecemos el valor en videomemoria 
-    INC DE                  ; Incrementamos puntero en sprite +    inc de                  ; Incrementamos puntero en sprite 
-    INC H                   ; Incrementamos puntero en pantalla (scanline+=1)+    inc h                   ; Incrementamos puntero en pantalla (scanline+=1)
     ENDR     ENDR
 </code> </code>
Línea 477: Línea 478:
 inicio: inicio:
  
-    LD B, 10+    ld b, 10
 bucle: bucle:
  
-    DJNZ bucle+    djnz bucle
     ;...     ;...
-    RET+    ret
  
     DISPLAY "-- Final del ensamblado --"     DISPLAY "-- Final del ensamblado --"
Línea 542: Línea 543:
  
     IF (MODO_DEBUG == 1)     IF (MODO_DEBUG == 1)
-        LD DE, mensaje +        ld de, mensaje 
-        CALL PrintString +        call PrintString 
-        CALL PrintFlags+        call PrintFlags
     ENDIF     ENDIF
  
Línea 600: Línea 601:
 \\  \\ 
  
-Ahora, sjasmplus sólo ensamblará e incluirá en el BIN/TAP final el código máquina de la rutina, si esta es llamada (''CALL'', ''JP/JR'', etc) o referenciada (''LD HLBuffer_Datos'').+Ahora, sjasmplus sólo ensamblará e incluirá en el BIN/TAP final el código máquina de la rutina, si esta es llamada (''call'', ''jp/jr'', etc) o referenciada (''ld hlbuffer_Datos'').
  
 Veamos el caso de nuestra librería ''utils.asm''. Cada vez que la incluímos en alguno de los ejemplos del curso, estamos añadiendo a nuestro programa varios cientos de bytes que ocupa el código ensamblado de la librería. Esto ocurre por el mero hecho de hacer un ''INCLUDE'', aunque no llamemos a ninguna función, o sólo llamemos a una de ellas. Veamos el caso de nuestra librería ''utils.asm''. Cada vez que la incluímos en alguno de los ejemplos del curso, estamos añadiendo a nuestro programa varios cientos de bytes que ocupa el código ensamblado de la librería. Esto ocurre por el mero hecho de hacer un ''INCLUDE'', aunque no llamemos a ninguna función, o sólo llamemos a una de ellas.
Línea 614: Línea 615:
 PrintSpace: PrintSpace:
     IFUSED     IFUSED
-    PUSH AF +    push af 
-    LD A, ' ' +    ld a, ' ' 
-    RST 16 +    rst 16 
-    POP AF +    pop af 
-    RET+    ret
     ENDIF     ENDIF
  
 PrintCR: PrintCR:
     IFUSED     IFUSED
-    PUSH AF +    push af 
-    LD A, 13 +    ld a, 13 
-    RST 16 +    rst 16 
-    POP AF +    pop af 
-    RET+    ret
     ENDIF     ENDIF
 </code> </code>
Línea 658: Línea 659:
     IF USAR_PRINTSPACE = 1     IF USAR_PRINTSPACE = 1
 PrintSpace: PrintSpace:
-    PUSH AF +    push af 
-    LD A, ' ' +    ld a, ' ' 
-    RST 16 +    rst 16 
-    POP AF +    pop af 
-    RET+    ret
     ENDIF     ENDIF
  
     IF USAR_PRINTCR = 1     IF USAR_PRINTCR = 1
 PrintCR: PrintCR:
-    PUSH AF +    push af 
-    LD A, 13 +    ld a, 13 
-    RST 16 +    rst 16 
-    POP AF +    pop af 
-    RET+    ret
     ENDIF     ENDIF
  
Línea 705: Línea 706:
  
 La desventaja de ''ALIGN'' es que el ensamblador lo que hace es rellenar con ceros el binario hasta conseguir que el siguiente byte del programa empiece en el múltiplo deseado, por lo que engordaremos el binario entre 0 (si da la casualidad de que ''tabla'' ya estaba en un múltiplo de 256) o 255 (si ''tabla'' casualmente ha caído 1 byte después de una dirección múltiple y necesitamos avanzar 255 bytes para llegar a la siguiente). La desventaja de ''ALIGN'' es que el ensamblador lo que hace es rellenar con ceros el binario hasta conseguir que el siguiente byte del programa empiece en el múltiplo deseado, por lo que engordaremos el binario entre 0 (si da la casualidad de que ''tabla'' ya estaba en un múltiplo de 256) o 255 (si ''tabla'' casualmente ha caído 1 byte después de una dirección múltiple y necesitamos avanzar 255 bytes para llegar a la siguiente).
 +
 +\\ 
 +De nuevo, **pasmo no tiene esta funcionalidad**, pero la podemos simular con macros:\\ 
 +
 +<code z80>
 +    ; Macro de alineacion para PASMO
 +    align   macro value
 +       if $ mod value
 +       ds value - ($ mod value)
 +       endif
 +       endm
 +
 +    align 256
 +</code>
  
  
 \\  \\ 
-===== z80asm =====+===== Una visión breve de z80asm =====
  
 El ensamblador z80asm es un mundo en sí mismo ya que permite generar código para gran cantidad de sistemas Z80 (desde el Z80 del Spectrum, a la variante del Z80 que utiliza la GameBoy clásica). El ensamblador z80asm es un mundo en sí mismo ya que permite generar código para gran cantidad de sistemas Z80 (desde el Z80 del Spectrum, a la variante del Z80 que utiliza la GameBoy clásica).
Línea 730: Línea 745:
 $ cat bucle.sym $ cat bucle.sym
 bucle                           = $0002 ; addr, local, , , , bucle.asm:4 bucle                           = $0002 ; addr, local, , , , bucle.asm:4
-variable                        = $000A ; addr, local, , , , bucle.asm:14+variable                        = $000a ; addr, local, , , , bucle.asm:14
  
 $ cat bucle.map $ cat bucle.map
-bucle                           = $82DE ; addr, local, , bucle, , bucle.asm:+bucle                           = $82de ; addr, local, , bucle, , bucle.asm:
-variable                        = $82E6 ; addr, local, , bucle, , bucle.asm:14 +variable                        = $82e6 ; addr, local, , bucle, , bucle.asm:14 
-__head                          = $82DC ; const, public, def, , , +__head                          = $82dc ; const, public, def, , , 
-__tail                          = $82E8 ; const, public, def, , , +__tail                          = $82e8 ; const, public, def, , , 
-__size                          = $000C ; const, public, def, , ,+__size                          = $000c ; const, public, def, , ,
  
 $ cat bucle.lis $ cat bucle.lis
Línea 743: Línea 758:
                                   ORG 33500                                   ORG 33500
      2      2
-      0000  06ff                  LD B, 255+      0000  06ff                  ld b, 255
                               bucle:                               bucle:
-      0002  c5                    PUSH BC +      0002  c5                    push bc 
-      0003  48                    LD CB +      0003  48                    ld cb 
-      0004  0600                  LD B, 0 +      0004  0600                  ld b, 0 
-      0006  c1                    POP BC+      0006  c1                    pop bc
      9      9
-    10  0007  10f9                  DJNZ bucle+    10  0007  10f9                  djnz bucle
     11     11
-    12  0009  c9                    RET+    12  0009  c9                    ret
     13     13
     14  000a  ffff              variable:      DW 65535     14  000a  ffff              variable:      DW 65535
Línea 760: Línea 775:
  Z80asm soporta directivas como ''ALIGN'', que no soporta pasmo, aunque sí sjasmplus.  Z80asm soporta directivas como ''ALIGN'', que no soporta pasmo, aunque sí sjasmplus.
  
 + El uso habitual de z80asm es el de generar "librerías" para Z88DK. Para ello se crea uno o más ficheros ASM dentro de los cuales está nuestro código en ensamblador con las rutinas que queremos que sean llamables desde C. Estas rutinas (así como las variables definidas con ''DB'' que nos interesen) se exportan con la directiva ''PUBLIC'' para que después sean visibles desde C. También podemos acceder desde ASM a variables y funciones externas al mòdulo si las declaramos con ''EXTERN''. Por ejemplo:
  
 \\  \\ 
 +<code z80>
 +; Fichero libreria.asm
 +SECTION code_user
 +
 +; exportamos el nombre de nuestra rutina para que sea usable desde C:
 +
 +PUBLIC _nuestra_rutina_asm
 +
 +; Variables o funciones externas globales de C (definidas en el
 +; programa en C) a las que queremos acceder desde este código ASM:
 +
 +EXTERN _una_variable_global_de_C
 +EXTERN _funcion_externa_de_C
 +
 +_nuestra_rutina_asm:
 +
 +   ; Llamar a función C
 +   call _funcion_externa_de_C
 +
 +   ; Acceder a variable C
 +   ld a, _una_variable_global_de_C
 +
 +loop:
 +   (...)
 +
 +   djnz loop            ; do it for all five members of array a[]
 +   ret
 +</code>
 +\\ 
 +
 + Este programa en ensamblador define una rutina la cual hace pública con ''PUBLIC'' para que sea visible a otros módulos del programa, y además declara con ''EXTERN'' una serie de símbolos externos (variables, funciones...) a los que accederá a lo largo del código.
 + 
 + A continuación podemos crear un programa en C que haga uso de esta librería:
 + 
 +\\ 
 +<code c>
 +// Fichero ejemplo.c
 +#include <stdio.h>
 + 
 +unsigned char una_variable_global_de_C = 128;
 + 
 +void funcion_externa_de_C(void)
 +{
 +   // Hacer algo 
 +   return;
 +}
 +
 +// Declaramos en C como extern nuestra rutina ASM (externa)
 +extern void nuestra_rutina_asm(void);
 + 
 +main()
 +{
 +   nuestra_rutina_asm();
 +   
 +   return 0;
 +}
 +</code>
 +\\ 
 +
 +Nótese el prefijo ''_'' (subrayado) que tienen en el fichero ''libreria.asm'' todos los símbolos que tienen que ser visibles entre C y ASM. Tanto ''_una_variable_global_de_C'', como ''_funcion_externa_de_C'', como ''_nuestra_rutina_asm'' lo tienen, y se utiliza dicho prefijo en el código en ASM. Estos símbolos se referencian después sin el prefijo de subrayado en el fichero ''ejemplo.c''. Por otra parte, los símbolos que serán "internos" del programa ensamblador, como ''loop'', se pueden escribir sin el subrayado.
 +
 +Ahora podemos compilar el programa de la siguiente forma:
 +
 +''zcc +zx -vn -clib=new ejemplo.c libreria.asm -o ejemplo.tap'' 
 +
 +Así, podemos crear diferentes módulos y librerías para tareas que requieran la máxima velocidad (impresión de gráficos, sonido, texto, etc) y utilizarlos dentro de programas en C. Pero eso nos obliga a realizar los ficheros ASM en formato z80asm, porque como se puede apreciar en la línea que hemos usado para compilar el programa, no se incluyen como librerías externas sino que se compilan junto al propio código C.
 +
 ===== En resumen ===== ===== En resumen =====
  
-Los diferentes programas ensambladores tienen una gran cantidad de directivas en común, pero también una serie de directivas propias de cada uno de ellos (o bien que unos las implementan y otros no, o bien que lo hacen con un nombre diferente).+Los diferentes programas ensambladores tienen una gran cantidad de directivas en común, pero también una serie de directivas propias de cada uno de ellos (o bien que unos las implementan y otros no, o bien que lo hacen con un formato o modo de uso diferente).
  
 Dejando de lado z80asm, que sólo recomendamos usar si necesitamos escribir código C+ASM para Z88DK, las dos opciones que nos quedan son **pasmo** y **sjasmplus**. Dejando de lado z80asm, que sólo recomendamos usar si necesitamos escribir código C+ASM para Z88DK, las dos opciones que nos quedan son **pasmo** y **sjasmplus**.
Línea 770: Línea 853:
 Si escribimos código ASM puro, sin utilizar las ventajas que proporcionan los ensambladores, podremos ensamblar el mismo programa de una forma sencilla en cualquiera de los 2, si acaso con cambios mínimos entre ellos. Si escribimos código ASM puro, sin utilizar las ventajas que proporcionan los ensambladores, podremos ensamblar el mismo programa de una forma sencilla en cualquiera de los 2, si acaso con cambios mínimos entre ellos.
  
-Pero en cuanto utilizamos cualquier funcionalidad especial del ensamblador, como las etiquetas locales o las macros ''REPT'', el código ya sólo ensamblará en aquel que hayamos elegido como referencia.+Pero en cuanto utilizamos cualquier funcionalidad especial del ensamblador, como las **etiquetas locales** o las macros ''REPT'', el código ya sólo ensamblará en aquel que hayamos elegido como referencia.
  
 Estas funcionalidades (etiquetas locales, macros, DEFINES, etc) son básicas para facilitarnos la vida cuando se programa en un lenguaje como ensamblador, así que esto implica que tenemos que elegir un programa ensamblador para nuestro código y ceñirnos a él durante todo el ciclo de vida de nuestro proyecto. Estas funcionalidades (etiquetas locales, macros, DEFINES, etc) son básicas para facilitarnos la vida cuando se programa en un lenguaje como ensamblador, así que esto implica que tenemos que elegir un programa ensamblador para nuestro código y ceñirnos a él durante todo el ciclo de vida de nuestro proyecto.
  
-Lo hemos dicho ya varias veces: nuestro consejo para seguir el curso, escribir un programa sencilla, comprobar una cosa o hacer un programa básico es **pasmo**, pero aconsejamos cambiar a **sjasmplus** (por directivas como ''ALIGN'' o ''IFUSED'') para los programas y juegos "finales" que queramos realizar.+Lo hemos dicho ya varias veces: nuestro consejo para seguir el curso, escribir un pequeño fragmento de código para comprobar algo, o hacer un programa básico o medio es **pasmo**, pero aconsejamos cambiar a **sjasmplus** (por directivas como ''ALIGN'' o ''IFUSED'') para los programas y juegos "finales" que queramos realizar. Estas dos últimas directivas pueden ser vitales en máquinas como el ZX Spectrum para optimizar rutinas y reducir el espacio que ocupan los programas.
  
  
Línea 789: Línea 872:
  
 \\  \\ 
-**[ [[.:indice|⬉]] | [[.:lenguaje_5|⬅]] | [[.:rutinas_rom|➡]] ]**+**[ [[.:indice|⬉]] | [[.:aritmetica|⬅]] | [[.:rutinas_rom|➡]] ]**
  • cursos/ensamblador/ensambladores.1705390403.txt.gz
  • Última modificación: 16-01-2024 07:33
  • por sromero