TASM menyikapi satu per satu

Sep 12 2020

Saat ini saya menerapkan Snake untuk universitas, dan kami harus menggunakan TASM untuk itu.

Data permainan utama saya ditata seperti ini (menggunakan sintaks C):

struct GameLine {
    uint8_t direction_bits[10];  // 2 bits per entry, the first entry is invalid since valid x positions start at one
    uint8_t collision_bits[5];  // 1 bit per entry, the first entry is again invalid but has to stay zero
    uint8_t aux;  // padding such that GameLine is 16 bytes big, also used to store other information at times.
};

struct GameData {
    struct GameLine lines[23];
} PHYSICAL_GAME_DATA;

Masalahnya adalah bahwa menulis bit arah setiap frame menimpa bit tabrakan baca untuk posisi x besar (38 adalah posisi maksimum, tetapi itu terjadi sebelumnya). Saya mengatakan "membaca bit tabrakan" karena saya tidak dapat memverifikasi di mana physical_game_datasebenarnya berada karena saya tidak tahu bagaimana menginstruksikan assembler ( tasm) dan / atau linker ( tlink) dan / atau debugger ( td) untuk menunjukkan hal itu kepada saya.

Deklarasi dalam kode saya adalah:

physical_game_data   DB 368 DUP (0)
; ..., Some `EQU`s for `aux` data I'm using to store other information
game_data EQU (offset physical_game_data) - 16  ; Since 1 <= y <= 23, this allows addressing a line via `game_data + (y << 4)`

Hal movyang paling saya khawatirkan di sini (ada beberapa lagi, tetapi ini adalah dua yang membuat bug terlihat) adalah dua ini:

; This one is for writing a new direction
mov     BYTE [ds:game_data + bx],   dh
; ...
; This one is for reading a collision bit to check if the player lost
mov     dl,     [ds:game_data + 10 + si]

Melihat mereka dalam tdmenghasilkan ini:

mov [bx+05AF],dh
; ...
mov dl,[si+05B8]

Namun, perbedaan antara 0x05AF dan 0x05B8 adalah 9, bukan 10. Saat ini saya telah "memperbaiki" masalah dengan menambahkan 11 di kode sumber sebagai gantinya, yang berarti bug tidak terjadi, tetapi saya lebih suka memperbaiki masalah ini dengan benar.

Saya berasumsi bahwa ini adalah saya yang salah paham tentang perakitan TASM atau x86 / x86-16, tetapi saya tidak tahu apa sebenarnya kesalahpahaman itu.

Berikut file lengkap yang menunjukkan masalah ini:


    .model  tiny
    .286

.data
datastart:
physical_game_data  DB 368 DUP (0)
; ..., Some `EQU`s for `aux` data I'm using to store other information
game_data           EQU (offset physical_game_data) - 16  ; Since 1 <= y <= 23, this allows addressing a line via `game_data + (y << 4)`

.code

        ORG 100h
start:
        mov         ax,                         seg datastart
        mov         ds,                         ax

        ; This one is for writing a new direction
        mov         BYTE [ds:game_data + bx],   dh
        ; ...
        ; This one is for reading a collision bit to check if the player lost
        mov         dl,                         [ds:game_data + 10 + si]

        ; Exit
        mov         ax,                         4C00h
        int         21h
end start

Dikompilasi menggunakan tasm MRE.ASM, tlink MRE.OBJdan dibuka dengan tdmenggunakan td MRE.EXE, kode yang didekompilasi berbunyi:

mov ax,48AF
mov ds,ax
mov [bx+0103],dh
mov dl,[si+010C]
mov ax,4C00
int 21

Di mana, sekali lagi, 0x10C - 0x103 adalah 9.

Jika menarik, saya menjalankan kode ini di bawah Dosbox.

Terima kasih!

Jawaban

5 RossRidge Sep 11 2020 at 23:34

Masalah Anda adalah kata kunci BYTE. Dalam mode MASM, kata kunci BYTE mengevaluasi ke ukuran BYTE: 1. Ini ditambahkan ke ekspresi dalam tanda kurung siku []karena tanda kurung siku terutama bertindak sebagai operator tambahan dalam mode MASM. Anda harus menulis BYTE PTR [ds:game_data + bx]sebagai gantinya, meskipun instruksi Anda berikutnya menunjukkan bahwa Anda juga bisa membiarkannya begitu saja.