KDBG ASM просмотр адреса элемента массива и значения с относительным смещением адреса

Версия KDBG: 3.0.1.

У меня есть матрица 10x10, определенная в C, например: char myArray[10][10] = { ' ', 'x', ... }, используемая в ASM.

В ASM я использую следующую строку для сравнения значения двух символов:

cmp BYTE[myArray+rax], 'x'
inc rax

rax, инициализированный 0, используется как счетчик циклов и относительное смещение адреса, оба до числа 100 (поскольку массив в памяти имеет длину 10 * 10 = 100 байт, верно?)

Итак, идея в том, что когда rax увеличивается на 1 (байт), в инструкции cmp я обращаюсь к следующему элементу в myArray.

Теперь, на панели выражений KDBG Watched, при использовании (&myArray+$rax) я ожидаю увидеть значение элемента, к которому я обращаюсь, но не могу этого сделать.

Пытался:

  1. Независимо от значения rax:

&myArray, показывает начальный адрес: (char)(*)[10][10] 0x5050a0 <myArray> и некоторые значения, разделенные запятыми. Не могу сказать, все ли это.

  1. Когда rax=5, например:

(&myArray+$rax), адрес: (char)(*)[10][10] 0x505294 <anotherArray+52>, есть разница в 500 от начального адреса, и он ссылается на другой массив, который я объявил в C.

Я не уверен, связан ли этот вопрос с синтаксисом KDBG или мое понимание того, как работают массивы в asm, неверно. Любая помощь приветствуется.

&myArray — это указатель на массив, поэтому добавление единицы к указателю сдвинет указатель на размер всего массива. попробуй (myArray[0]+$rax). (Я не знаю KDBG, так что это может быть неправильно)
MikeCAT 01.04.2022 16:30

Если myArray объявлено в C как char myArray[].., то myArray уже является адресом, поэтому &myArray может показаться чрезмерным, но, возможно, это работает в этом отладчике. Может быть, попробовать ((char*)myArray)+$rax, чтобы преобразовать myArray в указатель байта, затем добавить $rax — и, возможно, удалить это, как в ((char*)myArray)[$rax].

Erik Eidt 01.04.2022 18:06

@ErikEidt Черт, да! ((char*)myArray)[$rax] СДЕЛАЛА ЭТО! Не возражаете ли вы опубликовать ответ, расширяющий ваше объяснение? Так я лучше понимаю, что происходит. На панели отображается не адрес, а, по крайней мере, значение, и оно действительно правильное.

tec 01.04.2022 18:26
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
3
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда массив объявляется в C, имя массива относится к адресу всего массива, который является тем же значением, что и адрес его первого элемента.

В случае вашего примера char myArray[10][10] имя myArray является адресом элемента myArray[0], также известного как &myArray[0]. Если разрешено, конструкция &myArray будет иметь то же значение, что и myArray, но ее тип изменится:

  • myArray имеет тип char (*)[10], поэтому размер элемента равен 10.
  • &myArray имеет тип char (*)[10][10], поэтому размер элемента равен 100.

В C арифметика указателей автоматически масштабирует целочисленный индекс по размеру элемента, поэтому myArray+$rax, что означает, что масштабирование должно делать myArray+$rax*10 с явным масштабированием. В то время как &myArray+$rax будет масштабироваться $rax на 100.

Чтобы нейтрализовать масштабирование, преобразуйте указатель в байтовый указатель — размер элемента байтового указателя равен 1, поэтому неявное масштабирование эффективно подавляется (поскольку 1 является мультипликативной идентичностью).

Приведение (char *) myArray преобразует указатель в указатель байта, после чего вы можете эффективно выполнять арифметические операции с указателем байта без масштабирования C.

И разыменование с помощью $rax даст байтовый элемент, поэтому ((char*)myArray)[$rax].

Другие вопросы по теме