#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. Я предполагаю, что это не то, что вы хотите. Но трудно сказать вам, как исправить ваш код, потому что неясно, что он на самом деле должен делать.