32 个变量通常相当于 32 项大小的单个变量(数组)。
而不是使用变量名square_3_1_x,您会想到一个“映射函数”,例如,您将 4x4 方格寻址为每行 0,1,2..。
所以对于 1..4 范围内的行/列,square(row,column) 索引是 ((row-1)*4+(column-1))。
然后使用 *2 和 +0 表示 x / +1 表示 y:3_1_x 是 16,3_2_y 是 19。
或 +0 表示 x 和 +16 表示 y(3_1_x 是 8,3_2_y 是 25)。
或者你能想到的任何你自己喜欢的映射。
假设您想在 32b x86 汇编程序(NASM 语法)中获取磁盘在第 3 行 (1..4) 和第 2 列 (1..4) 的 [x,y] 位置(我喜欢你的做法) '不要指定你的平台和语法,所以回答的人可以选择他们想要的任何东西,然后你必须理解完全陌生的语法,并将其转换为你的最终来源,你非常慷慨):
discPositions: times 32 dd 0 ; 16+16 for x+y couples (16 = 4x4).
GetDiscPosition:
; input: row (1..4) in eax, column (1..4) in ebx
; output: x position in eax, y position in ebx
dec eax ; row-1
dec ebx ; column-1
shl eax,2 ; (row-1)*4
add eax,ebx ; (row-1)*4+(column-1)
shl eax,3 ; ((row-1)*4+(column-1))*2*4
; *2 to cover [x,y] pairs, *4 to respect data size (DWORD)
; so here eax is byte offset to [x,y] couple in discPositions array
; it would make sense to have that offset calculation in another
; subroutine, so you can reuse it for SetDiscPosition routine
; Now just return the [x,y] stored in the 128B memory array labeled discPositions
mov ebx,[discPositions+eax+4] ; fetch y position
mov eax,[discPositions+eax+0] ; fetch x position
ret
; ... now somewhere in your code, where you want to get disc's x,y for square(3,4)
mov eax,3
mov ebx,4
call GetDiscPosition
; eax now has x position, ebx has y position
; ...
编辑:
好吧,既然这个答案得到了两次投票,看起来这些东西可能对其他人有帮助(感谢问题的慷慨措辞?)。
所以我将从第二个共同的角度来解决这个问题。假设您确实有 32 个变量,例如 RPG 中角色的属性,有些只需要 byte (strength),有些需要 qword (experience),并且很快就会想起 health 的索引为 4,而 prestidigitation 的索引为 29。 p>
此外,您通常只需要其中几个用于更新的特定部分,例如计算用剑造成伤害的角色不需要 elocution 和 charisma,但你也需要需要几个不同的角色(玩家对敌人)具有相同的统计数据,所以你仍然缺少寄存器。
在这种情况下,我经常只是模仿类似 C 的结构:
; defining "PERSON" structure
PERSON_X equ 0 ;2B
PERSON_Y equ PERSON_X+2 ;2B
PERSON_HP equ PERSON_Y+2 ;4B
PERSON_MANA equ PERSON_HP+4 ;4B
PERSON_LEVEL equ PERSON_MANA+4 ;2B
;...
PERSON_PRESTIDIGITATION equ PERSON_ELOCUTION+1 ;1B
PERSON_SIZE equ PERSON_PRESTIDIGITATION+1
; reserving array for 4 player's characters
playersParty: resb 4*PERSON_SIZE
; ... somewhere in the code:
; teleporting whole party at x,y=(32,64)
MOV ax,32 ; new x
MOV bx,64 ; new y
MOV ecx,4
MOV edi,playersParty
setAllPartyMembers:
MOV [edi+PERSON_X],ax
MOV [edi+PERSON_Y],bx
ADD edi,PERSON_SIZE
LOOP setAllPartyMembers
NASM 实际上有“struc”宏,这样可以省去手动计算正确尺寸的麻烦(就像我在上面所做的那样):
; defining "PERSON" structure with base offset 13 in NASM
; (but you want particular attributes aligned to their size boundary)
STRUC person, 13
alignb 2
.x: resw 1
.y: resw 1
alignb 4
.hp: resd 1
.mana: resd 1
.level: resw 1
;...
.prestidigitation: resb 1
.size:
ENDSTRUC
; player single person with some basic init (e.g. in .data segment)
SEGMENT .data
playerPerson1: ISTRUC person
AT person.hp, dd 100
AT person.mana, dd 100
AT person.level, dw 1
IEND
; .. somewhere in the code:
; moving player by ax on x, bx on y
; and decreasing hp by 1 (it's a trap!)
MOV edi,playerPerson1
ADD [edi+person.x],ax
ADD [edi+person.y],bx
DEC DWORD [edi+person.hp]
; ...
(我的代码我没有调试过,所以这里可能有bug,但希望原理能看懂就明白了)