TASM endereçando por um

Sep 12 2020

No momento, estou implementando o Snake para a universidade e temos que usar o TASM para isso.

Meus dados principais do jogo são dispostos assim (usando a sintaxe 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;

O problema é que escrever os bits de direção de cada quadro sobrescreve os bits de colisão lidos para grandes posições x (38 é a posição máxima, mas isso acontece antes). Eu digo "ler bits de colisão" porque não fui capaz de verificar onde o physical_game_datarealmente reside porque não sei como instruir o montador ( tasm) e / ou vinculador ( tlink) e / ou depurador ( td) para me mostrar isso.

As declarações em meu código são:

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)`

Os movs que mais me preocupam aqui (existem mais alguns, mas são os dois que tornam o bug visível) são estes dois:

; 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]

Olhando para aqueles em, no tdentanto, resulta o seguinte:

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

A diferença entre 0x05AF e 0x05B8, entretanto, é 9, não 10. No momento, "consertei" o problema adicionando 11 no código-fonte, o que significa que o bug não ocorre, mas prefiro corrigir esse problema adequadamente.

Estou supondo que isso seja um mal-entendido sobre TASM ou montagem x86 / x86-16, mas não sei exatamente o que é esse mal-entendido.

Aqui está um arquivo completo que apresenta esse problema:


    .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

Compilado usando tasm MRE.ASM, tlink MRE.OBJe aberto tdusando td MRE.EXE, o código descompilado lê:

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

Onde, novamente, 0x10C - 0x103 é 9.

Se for do seu interesse, estou executando este código no Dosbox.

Obrigado!

Respostas

5 RossRidge Sep 11 2020 at 23:34

Seu problema é a palavra-chave BYTE. No modo MASM, a palavra-chave BYTE é avaliada como o tamanho de um BYTE: 1. Isso é adicionado à expressão entre colchetes, []pois os colchetes atuam principalmente como um operador de adição no modo MASM. Em BYTE PTR [ds:game_data + bx]vez disso, você precisaria escrever , embora sua próxima instrução demonstre que você também pode simplesmente deixá-lo de fora.