Как вы индексируете массив символов с помощью register или QWORD в x64 MASM?

#arrays #assembly #character #x86-64 #masm

#массивы #сборка #характер #x86-64 #masm

Вопрос:

Я читал похожие сообщения по этому вопросу, но просто не могу найти ничего, что помогло бы мне решить мою проблему. По сути, я хочу изменить запись в массиве символов в определенной точке, поэтому просто индексирую ее. Я знаю, как это сделать с помощью магического числа (т.Е. Просто помещая в буфер [2] или что-то в этом роде), но я получаю ошибки, когда пытаюсь проиндексировать массив символов числовым значением, хранящимся в регистре или QWORD.

Итак, у меня есть массив символов, называемый buffer

 buffer BYTE 4097 DUP (0)
 

и у меня также есть QWORD с именем parseNum

 parseNum QWORD 0
 

Вот раздел кода, который вызывает у меня проблемы:

 testJmp:
mov rbx, parseNum
xor buffer[rbx], 2
add parseNum, 2
cmp parseNum, 4097
jne testJmp
 

Предполагается, что этот код перебирает массив символов и применяет операнд XOR к каждой записи. Однако я могу это сделать, только если я могу индексировать значение, которое изменяется с каждым циклом. Когда я пытаюсь просто использовать xor buffer[parseNum], 2 , я получаю сообщение об ошибке, которое читается error A2101: cannot add two relocatable labels в этой строке кода. Когда я пытаюсь переместить parseNum в rbx, а затем ввести rbx в качестве индекса, я также получаю сообщение об ошибке следующего содержания: error LNK2017: 'ADDR32' relocation to 'buffer' invalid without /LARGEADDRESSAWARE:NO . Я в полной растерянности и полностью застрял. Надеюсь, я правильно отформатировал этот вопрос, поскольку знаю, что многие в stackoverflow относятся к этому очень серьезно. Это один из моих самых первых постов, поэтому я надеюсь, что я сделал это правильно и в соответствии со стандартами.

Подводя итог, есть ли способ индексировать массив символов с помощью массива или переменной? Спасибо за любую помощь! Кроме того, я студент, а MASM и Assembly — это то, чему я все еще очень много учусь и в чем пока не разбираюсь, поэтому, если я пропустил что-то очевидное, вот почему. Еще раз спасибо за вашу помощь!

РЕДАКТИРОВАТЬ: я предполагаю, что мне нужны как адрес буфера, так и parseNum для загрузки в регистры. Я попытался внести эти изменения, как показано здесь:

 lea rbx, buffer
mov rax, parseNum
xor buffer[rax], 2
 

но я по-прежнему получаю те же ошибки, что и раньше.

РЕДАКТИРОВАТЬ: Благодаря некоторым очень полезным комментариям у меня получилось, вот код:

     testJmp:
lea rdx, buffer
mov rbx, parseNum
mov al, [rdx   rbx]
xor al, 2
mov [rdx   rbx], al
add parseNum, 1
cmp parseNum, 4097
jne testJmp
 

по сути, буфер и parseNum должны быть загружены в регистры. Затем я получаю доступ к индексу, добавляя два регистра и перемещая их в al. Затем я могу применить xor и переместить его обратно в индекс.

Комментарии:

1. Сначала загрузите адрес buffer в регистр, используя lea .

2. @fuz Я только что попробовал это, добавив строку в верхней части цикла, которая гласит ` lea rbx, buffer`, а затем попытался загрузить в parseNum в качестве индекса, но все равно получил те же ошибки :/

3. Да, конечно, если вы тоже не загружаетесь parseNum в регистр, проблема не исчезнет. Оба должны быть в регистрах. Это связано с тем, что без /LARGEADDRESSAWARE:NO переключателя нельзя предположить, что метки находятся в первых 2 ГБ памяти.

4. @fuz: но код OP использует только parseNum один, а не с другим регистром, поэтому для этого следует использовать адресацию RIP-relative. Я думаю, что MASM всегда использует RIP-relative, когда это возможно, в отличие от GAS, где вам нужно mov rbx, parseNum[RIP] . (Конечно, загрузка значения в регистр была бы более эффективной, чем сохранение его в памяти).

5. Еще одна ошибка: если parseNum начинается с 0, и вы добавляете к нему 2 каждый раз, вы будете обрабатывать только каждый второй байт, и ваш цикл не завершится, потому что он никогда не будет равен нечетному числу 4097. Я предполагаю, что это не то, что вы хотите. Но трудно сказать вам, как исправить ваш код, потому что неясно, что он на самом деле должен делать.