问题描述
我目前正在为大学实施Snake,为此我们必须使用TASM。
我的主要游戏数据的布局如下(使用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;
问题在于,每帧写入方向位会覆盖较大x位置(最大位置38,但较早发生)的读取冲突位。我之所以说“读取冲突位”是因为我无法验证physical_game_data
的实际位置,因为我不知道如何指示汇编程序(tasm
)和/或链接程序({{1 }})和/或调试器(tlink
)告诉我。
我的代码中的声明是:
td
我在这里最担心的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)`
(这是另外几个,但是这两个使该错误可见)是
mov
查看; 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]
中的内容会得出以下结论:
td
0x05AF和0x05B8之间的差是9,而不是10。我目前通过在源代码中添加11来“修复”了该问题,这意味着该错误不会发生,但我宁愿解决此问题正确发行。
我以为这是我对TASM或x86 / x86-16汇编的误解,但我不知道到底是什么误解。
以下是存在此问题的完整文件:
mov [bx+05AF],dh
; ...
mov dl,[si+05B8]
使用
.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
,tasm MRE.ASM
进行编译,并使用tlink MRE.OBJ
用td
打开,反编译后的代码为:
td MRE.EXE
再一次,0x10C-0x103是9。
谢谢!
解决方法
您的问题是BYTE关键字。在MASM模式下,BYTE关键字的计算结果为BYTE的大小:1.将其添加到方括号[]
中的表达式中,因为方括号主要充当MASM模式下的加法运算符。尽管下一条指令说明您也可以将其省略,但您需要写BYTE PTR [ds:game_data + bx]
。