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 08:05] – [Directivas comunes entre 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 66: 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 143: 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 187: Línea 187:
 _loop: _loop:
     ...     ...
-    JR NZ, _loop +    jr nz, _loop 
-    RET+    ret
  
 Rutina2: Rutina2:
Línea 194: Línea 194:
 _loop: _loop:
     ...     ...
-    JR Z, _loop +    jr z, _loop 
-    RET+    ret
 </code> </code>
 \\  \\ 
Línea 221: 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 236: 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 267: 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 280: 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 322: 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 432: Línea 432:
 .loop: .loop:
     ...     ...
-    JR NZ, .loop +    jr nz, .loop 
-    RET+    ret
  
 Rutina2: Rutina2:
Línea 439: 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 453: 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 478: 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 543: 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 601: 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 615: 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 659: 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 706: 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>
  
  
Línea 731: 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 744: 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 781: Línea 795:
  
    ; Llamar a función C    ; Llamar a función C
-   CALL _funcion_externa_de_C+   call _funcion_externa_de_C
  
    ; Acceder a variable C    ; Acceder a variable C
-   LD A, _una_variable_global_de_C+   ld a, _una_variable_global_de_C
  
 loop: loop:
    (...)    (...)
  
-   DJNZ loop            ; do it for all five members of array a[] +   djnz loop            ; do it for all five members of array a[] 
-   RET+   ret
 </code> </code>
 \\  \\ 
Línea 858: Línea 872:
  
 \\  \\ 
-**[ [[.:indice|⬉]] | [[.:lenguaje_5|⬅]] | [[.:rutinas_rom|➡]] ]**+**[ [[.:indice|⬉]] | [[.:aritmetica|⬅]] | [[.:rutinas_rom|➡]] ]**
  • cursos/ensamblador/ensambladores.1705392351.txt.gz
  • Última modificación: 16-01-2024 08:05
  • por sromero