• Domingo 16 de Mayo de 2021, 02:41

Autor Tema:  Assembler inline  (Leído 1734 veces)

123celes

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Assembler inline
« en: Viernes 24 de Octubre de 2008, 20:18 »
0
Hola, ¿Cómo están todos? (espero que bien ), yo por mi parte me encuentro muy bien y sigo estudiando distintas rutinas de ensamblador orientadas a la programación gráfica.

En realidad el código que estoy estudiando en un Assembly inline, ósea que esta embebido en Turbo Pascal, pero igual me funciona muy bien a la hora de optimizar ciertos códigos.

Les escribo por que quería consultarles sobre una determinada rutina, la cual creo haber entendido en su mayoría:

Rutina de borrado.
La rutina de borrado lo que hace es rellenar un segmento de la memoria con un byte especificado (del 0 - 255), si rellenamos con el byte 0 y este representa el color negro 'borraremos' la pantalla con el color 0, si borramos con el byte 25 y este representa el color naranja, 'borraremos' la pantalla con el color naranja. Esta rutina también debe estar optimizada al máximo ya que se realiza muchas veces por ciclo. También se usan registros de 32 bits:

  -rutina de borrado en ensamblador:

Código: Text
  1.  
  2. PROCEDURE Fill64k (Where:word;Col : Byte); assembler;
  3. asm
  4.     push    es
  5.     mov     cx, 16000;
  6.     mov     es,[where]
  7.     xor     di,di
  8.     mov     al,[col]
  9.     mov     ah,al
  10.     mov     dx, ax
  11.     db      $66, $C1, $E0, $10   {shl eax, 16}
  12.     mov     ax, dx
  13.     db      $F3, $66, $AB          {rep stosd}
  14.     pop     es
  15. End;
  16.  
  17.  

Lo que quiero preguntar es:

1)Por qué en la linea 11
db      $66, $C1, $E0, $10   {shl eax, 16}

No coloca directamente shl eax, 16 ¿Es por que esas instrucciones no existen en el Assembly Inline de Turbo Pascal y tiene que usar los prefijos para que el procesador lo entienda?

2)En las lineas 10 y 12:
mov     dx, ax

mov     ax, dx

No comprendo que trabajo realizan, ¿Para que sirven?

Bueno eso es todo, muchas gracias por leer mi mensaje.

Les dejo estos sitios de interes:

geocities.com/SiliconValley/code/2632/ Programación de videojuegos en Turbo Pascal

ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/source/00index.html Un excelente sitio con mucho código fuente

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Assembler inline
« Respuesta #1 en: Viernes 24 de Octubre de 2008, 21:23 »
0
1) Supongo que si, para comprobarlo tendria que intentar ensamblar la instruccion en cuestion, mejor lo haces vos que tenes las herramientas y el codigo a mano.

2) A. Guarda AX (que es modificado por shl eax, 16) en DX.
    B. Restaura AX de DX (que obviamente no sufre modificacion).

Entonces te quedara un eax de este estilo, siendo AX al principio 0FFFFh: 0FFFFFFFFh.

Y los pasos completos (no solo incluyendo esas dos lineas) serian:
A. EAX=0000FFFFh por mov al,[col] y mov ah,al.
B. EAX=FFFF0000h por el shl eax, 16.
C. EAX=FFFFFFFFh por el mox ax, dx.

Todo esto para copiar de 4 bytes cada vez con stosd (D de DWORD, double word, doble palabra, 4 bytes).

Como te dije antes estos juegos - y su codigo claro esta - son arcaicos y obsoletos.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

m0skit0

  • Miembro de PLATA
  • *****
  • Mensajes: 2337
  • Nacionalidad: ma
    • Ver Perfil
    • http://fr33kk0mpu73r.blogspot.com/
Re: Assembler inline
« Respuesta #2 en: Viernes 24 de Octubre de 2008, 21:44 »
0
Cita de: "123celes"
¿Es por que esas instrucciones no existen en el Assembly Inline de Turbo Pascal y tiene que usar los prefijos para que el procesador lo entienda?

Efectivamente, supongo que porque no tendrá soporte para los registros extendidos de 32 bits del 386 y superiores.

Cita de: "123celes"
En las lineas 10 y 12:
mov dx, ax
mov ax, dx
No comprendo que trabajo realizan, ¿Para que sirven?

Primero tienes que entender lo que hace REP STOSD. REP, creo que ya lo comentamos en otro post, repite la instrucción tantas veces como indique CX y por cada iteración aumenta/decerementa DI y SI en tantas unidades como bytes procese la instrucción. STOSD copia EAX a ES:EDI (4 bytes por tanto). Aquí te dejo comentado el código:

Código: ASM
  1. PROCEDURE Fill64k (Where:word;Col : Byte); assembler;
  2. asm
  3.     ; Guardamos ES en la pila
  4.     push    es
  5.     ; 16000 veces
  6.     mov     cx, 16000;
  7.     ; Movemos el valor de la variable a ES
  8.     mov     es,[where]
  9.     ; Ponemos DI a cero
  10.     ; Error: esto supone que los 2 bytes más altos de EDI
  11.     ; están a cero, por tanto puede producir errores si no es así
  12.     xor     di,di
  13.     ; Movemos el valor con que queremos rellenar la zona de memoria a AL (1 byte)
  14.     mov     al,[col]
  15.     ; Copiamos ese mismo byte a AH
  16.     mov     ah,al
  17.     ; Ahora viene lo que te da el dolor de cabeza :)
  18.     ; Copia AX en DX (como una variable temporal)
  19.     mov     dx, ax
  20.     ; Mueve 16 posiciones a la izquierda EAX, es decir, rellena los 16 bits altos de EAX. AX queda a 0.
  21.     db      $66, $C1, $E0, $10   {shl eax, 16}
  22.     ; Vuelve a poner DX en AX, con lo que nos queda el byte con el que rellenar la zona de memoria
  23.     ; repetido en los 4 bytes de EAX.
  24.     mov     ax, dx
  25.     ; Copia EAX 16000 veces en ES:EDI
  26.     ; Rellena 16000 x 4 bytes = 64000 bytes = 64K con el valor de Col
  27.     db      $F3, $66, $AB          {rep stosd}
  28.     ; Recupera el ES original
  29.     pop     es
  30. End;
  31.  

EDIT: sabía que se me iba a adelantar, jejejeje... Y como alguien dijo, programar es darle a la imaginación  :lol:

123celes

  • Nuevo Miembro
  • *
  • Mensajes: 12
    • Ver Perfil
Re: Assembler inline
« Respuesta #3 en: Sábado 25 de Octubre de 2008, 14:59 »
0
Muchas gracias por su respuesta. Creo que ya lo tengo el color de un píxel en este modo va de 0-255, si yo quiero poner toda la pantalla de blanco (63d  11111111b)

Entonces le paso como parámetro la dirección de la memoria de video A000:0000 que va en el parámetro Where tamaño Word y el color deseado Col 11111111b que es blanco de tamaño byte

Primero guardo el contenido de es, luego pongo 16000 en cx por que es el número de repeticiones que voy a hacer con rep stosd por que con cada pasada voy a dibujar con píxeles de color blanco. Luego es recibe la dirección de la memoria de video, di se coloca a cero, por que los bytes se van a copiar desde eax que tiene 4 bytes a ES:E(DI), para que comience desde cero. El color elegido va del Col a al y de al a ah, luego se salva ax en dx como dato temporal y luego los valores de al y ah se desplazan 16 lugares a la izquierda para que cuando se copia el valor de dx a ax que el color blanco (11111111b) 4 veces, en los 4 bytes de eax. Luego de realizada la acción E(DI) es incrementado en 4 (doble palabra) para continuar con los próximos 4 bytes de la memoria de video, y al final se recupera el valor de es y la pantalla queda con el color seleccionado en este caso blanco. Muchas gracias a todos por sus comentarios, no lo hubiera sacado nunca sin su ayuda.

También encontré estos enlaces de referencia si les interesa.

investigacion.frc.utn.edu.ar/labsis/Publicaciones/InvesDes/3deng/Intro/13h.htm

ing.unlpam.edu.ar/~material/arquitectura/Arquitectura-PC-dos.html

paginespersonals.upcnet.es/~rvm1/e_graf.html



Procedure fill64k (Where:word;Col : Byte); assembler;
asm
   push    es
   mov     cx, 16000;
   mov     es,[where]
   xor     di,di
   mov     al,[col]
   mov     ah,al
   mov     dx, ax
   db      $66, $C1, $E0, $10         {shl eax, 16}
   mov     ax, dx
   db      $F3, $66, $AB              {rep stosd}     {vivan los 32 Bits :)}
   pop     es
End;