2012-06-15 12 views
5

? Estoy escribiendo un juego en C++ para MS-DOS y estoy incluyendo un ensamblado en línea para la velocidad. Este bloque de código particular dibujaría una estrella en la memoria de video (0A000h). El problema con mi código es que solo dibuja un píxel en cualquier color en el que esté establecido dh. Por lo que sé, mov dx, 00007h es equivalente a establecer dh a 0 y dl a 7. ¿Qué pasa?¿Cuál es el problema con mi código de ensamblaje

El código C/C++ equivalente (o al menos mi intención) se comenta al lado de cada línea. Mi compilador es turbo C++ 3.0. Intento usar solo las instrucciones 8086/8088.

También sé qué tan antiguo es MS-DOS así que no me diga que escriba código para un compilador/sistema operativo más nuevo. Escribir código para dos es una afición mía.

pixelOffset = x + (y << 6) + (y << 8); 

_asm { 
    mov ax, WORD PTR pixelOffset 
    mov di, ax 
    mov ax, 0A000h   ;pointer to the video memory 
    mov es, ax 
    mov dx, 00007h   ;indexed color 00 and 07 
    mov cx, 0000Fh   ;indexed color white 0F 
    add ax, 2    ;pixelOffset += 2; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 319   ;pixelOffset += 319; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 317   ;pixelOffset += 317; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], cx  ;videomem[pixelOffset] = WHITE; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 317   ;pixelOffset += 317; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dl  ;videomem[pixelOffset] = LIGHT_GRAY; 
    add ax, 1    ;pixelOffset += 1; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
    add ax, 319   ;pixelOffset += 319; 
    mov es:[di], dh  ;videomem[pixelOffset] = BLACK; 
} 
+4

¿Estás escribiendo * un ** DOS ** juego? Eso es tan asombroso. –

+0

+1 para la nostalgia de los juegos de MS-DOS! –

+0

@John Dibling: ya lo voy a poner en sourceforge cuando haya terminado – PgrAm

Respuesta

5

creo que se ha olvidado de actualizar di después de actualizar hacha

add ax,1 
mov di,ax ;don't forget this line 
mov es:[di],dl 
+0

muchas gracias, funciona ahora. Soy realmente malo en el ensamblaje – PgrAm

+1

Normalmente solo estoy programando en 32 bits, pero supongo que la instrucción 'inc' existe en 16 bits. ¿No puedes usar 'inc di' sin volver a ax de todos modos? Realmente no veo por qué no estás editando 'di' directamente todo el tiempo. – Nyerguds

3

No parece que estés incrementando "di", ¿o sí? ¿Quizás quisiste decir "movsb"?

0

La instrucción LEA también existe en 16 bits:

lea di,[di+1] ; substitute for "inc di" and/or "add di,1" , if we do not need a flag 

Dirk

0

No hay necesidad de incrementar la base usando ax - primero; también está el modo de direccionamiento con el desplazamiento única (también considerado como dirección absoluta)

mov es:[1001], dh 
mov es:[1002], dl 
mov es:[1535], cl 

Para hacer que sea más útil - puede usar eso con offset, lo que podría por ejemplo. trabajar como el centro de su estrella:

mov es:[di - WIDTH], ... ;; pixel/character above the current cursor 
mov es:[di + WIDTH], ... ;; pixel/char below 
mov es:[di + 1], ...  ;; pixel right to the origin etc. 

Al utilizar el prefijo reemplazo de segmento es: es costoso. En cambio, sugeriría usar

mov ax, 0a000h 
push ds 
mov ds, ax 
// 
mov [di + offset], cl  ;; this pays off when writing several pixels 
// 
pop ds    ;; restore DS after you have copied your stuff 
Cuestiones relacionadas