32 переменных обычно эквивалентно одной переменной (массиву) размером 32 элемента.
И вместо использования имени переменной square_3_1_x
вы имеете в виду «функцию сопоставления», например, вы адресуете квадраты 4x4 как 0,1,2 .. на строку.
так square(row,column)
указатель есть ((row
-1) * 4 + (column
-1)) для строки/столбца в диапазоне 1..4.
А затем либо использовать * 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
).
Или что бы вы ни думали о своем собственном воображаемом картотеке.
Предположим, вы хотите получить позицию [x, y] диска в строке 3 (1..4) и столбце 2 (1..4) в ассемблере 32b x86 (синтаксис NASM) (мне нравится, как вы не указывали вашу платформу и синтаксис, поэтому люди, отвечающие, могут выбирать все, что пожелают, и тогда вам нужно будет понять полностью чуждый синтаксис для вас и преобразовать его в ваш окончательный источник, очень щедро от вас):
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
; ...
редактировать: Ну, так как этот ответ был upvoted дважды, похоже, этот материал может быть полезным для других (благодаря щедрой формулировке вопроса?).
Так что я займусь этим из второй общей перспективы. Допустим, вы действительно есть 32 переменных, как, например, атрибуты персонажа в RPG, некоторые нуждаются только byte
(силы), некоторые в qword
(опыт), и это скоро станет супер раздражает помнить, что здоровье имеет индекс 4
и престиж имеет индекс 29
.
Также часто требуется только несколько из них для определенной части обновления, как вычисления символа делает урон от меча не нуждается в ораторском искусстве и харизме, но и вам нужен несколько различных персонажей (игрок против врага) с одинаковой статистикой, поэтому у вас все еще есть нехватка регистров.
В таком случае я часто просто подражать 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]
; ...
(я не отлаживать код, так что может быть ошибка здесь и там, но, надеюсь, этот принцип легко понять, просто прочитав его)
Вряд ли кто-нибудь может ответить на этот вопрос, не в наименее подробнее о том, как структурирован код. В любом случае, общий совет - избегать глобальных переменных и использовать локальные. – m0skit0
На каком языке вы владеете? – Richard