2012-06-15 37 views
5

Vì vậy, tôi đang viết một trò chơi bằng c + + cho MS-DOS và tôi bao gồm một số lắp ráp nội tuyến cho tốc độ. Khối mã đặc biệt này sẽ vẽ một ngôi sao vào bộ nhớ video (0A000h). Vấn đề với mã của tôi là nó chỉ vẽ một pixel trong bất kỳ màu nào dh được đặt thành. Theo như tôi biết mov dx, 00007h tương đương với thiết lập dh thành 0 và dl thành 7. Điều gì là sai?Có gì sai với mã assembly của tôi

Mã C/C++ tương đương (hoặc ít nhất là ý định của tôi) được nhận xét bên cạnh mỗi dòng. Trình biên dịch của tôi là turbo C++ 3.0. Tôi đang cố gắng chỉ sử dụng hướng dẫn 8086/8088.

Ngoài ra tôi biết cách MS-DOS cũ như vậy không cho tôi biết để viết mã cho trình biên dịch/hệ điều hành mới hơn. Viết mã cho dos là một sở thích của tôi.

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

Bạn đang * viết * ** ** trò chơi? Thật tuyệt. –

+0

+1 cho nỗi nhớ game MS-DOS! –

+0

@ John Dibling: ya và tôi sẽ đặt nó lên trên sourceforge khi tôi hoàn thành – PgrAm

Trả lời

5

Tôi nghĩ rằng bạn đã quên để cập nhật di sau khi cập nhật rìu

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

cảm ơn bạn rất nhiều nó hoạt động ngay bây giờ. Tôi thực sự xấu tại lắp ráp – PgrAm

+1

Tôi thường chỉ lập trình trong 32 bit, nhưng tôi giả sử lệnh 'inc' tồn tại trong 16-bit. Bạn không thể chỉ sử dụng 'inc di' mà không quay trở lại axe? Tôi không thực sự hiểu tại sao bạn không chỉ chỉnh sửa trực tiếp 'di'. – Nyerguds

3

Dường như bạn chưa từng tăng "di", phải không? Có lẽ bạn có nghĩa là "movsb"?

0

Các hướng dẫn lea cũng tồn tại trong 16 bit:

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

Dirk

0

Không cần để tăng cơ sở sử dụng ax - trước tiên; có cũng là chế độ giải quyết với dịch chuyển chỉ (hay còn được coi là địa chỉ tuyệt đối)

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

Để làm cho điều đó hữu ích hơn - bạn có thể sử dụng với bù đắp, mà có thể ví dụ. làm trung tâm của ngôi sao của bạn:

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. 

Sử dụng tiền tố ghi đè phân đoạn es: là tốn kém. Thay vào đó, tôi khuyên bạn nên sử dụng

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 
Các vấn đề liên quan