5

所以我正在用 C++ 为 MS-DOS 编写一个游戏,并且我包括一些内联汇编来提高速度。这个特殊的代码块会在视频内存(0A000h)中画一个星号。我的代码的问题是它只以 dh 设置的任何颜色绘制一个像素。据我所知 mov dx, 00007h 相当于将 dh 设置为 0 将 dl 设置为 7。有什么问题?

等效的 C/C++ 代码(或至少我的意图)在每一行旁边注释。我的编译器是 Turbo C++ 3.0。我试图只使用 8086/8088 指令。

我也知道 MS-DOS 有多老,所以不要告诉我为更新的编译器/操作系统编写代码。为dos编写代码是我的一种爱好。

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

4 回答 4

5

我认为您在更新 ax 后忘记更新 di

add ax,1
mov di,ax ;don't forget this line
mov es:[di],dl
于 2012-06-15T16:31:50.820 回答
3

看起来你从来没有增加“di”,是吗?也许您的意思是“movsb”?

于 2012-06-15T16:29:17.797 回答
0

lea 指令也存在于 16 位中:

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

短剑

于 2014-02-27T07:32:25.143 回答
0

无需使用ax-- first 来增加基数;还有只有位移的寻址模式(也被认为是绝对地址)

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

为了使它更有用——您可以将它与偏移一起使用,例如。以你的星星为中心:

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.

使用段覆盖前缀es:的成本很高。相反,我建议使用

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
于 2014-02-27T07:47:00.740 回答