Ошибка определения местоположения нарушения прав доступа при использовании массивов в сборке x86 c ++ - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь обновить указанный индекс c в массиве, используя x86. Я получаю сообщение об ошибке «Ошибка записи доступа ...» в строке: mov [ebx+ecx], eax. Что я могу сделать, чтобы это исправить.

Пример кода:


int main() {

   float price[ ] = { 22.1, 34.44, 567.33, 2.45 };
   float newPrice = 32.55;
   int newPriceIndex = 1; // replace 34.44 with 32.55


   __asm {
      mov eax, newPrice
      mov ebx, price
      mov ecx, newPriceIndex
      mov [ebx+ecx], eax
   }

   cout << "price[newPriceIndex] = " << price[newPriceIndex]; //should show 32.55

   return 0

}

1 Ответ

2 голосов
/ 30 марта 2020

mov ebx, price загружает значение из памяти, а не указатель, как обычно для синтаксиса MASM с mov reg, symbol. Это объект массива, а не указатель, и (я думаю) не "распадается" на указатель при использовании таким образом .

Нет указателя на этот массив куда угодно в памяти вы можете загрузить с mov, потому что это не так, как работают C массивы.

Используйте отладчик, чтобы увидеть значение регистра. Также посмотрите на сгенерированный компилятором сборка, используя disassembly-view в вашем отладчике. Таким образом, вы можете видеть, что он собран в mov ebx, [ebp + something], загружая price[0].

Написание asm (особенно inline asm) без отладчика похоже на попытку построить робота с завязанными глазами; это пустая трата вашего и чужого времени.


mov [price + ecx*4], eax может сработать, если MSV C скомпилирует это в [ebp + constant + ecx*4] режим адресации для вас.

Если нет, используйте mov ebx, [price] вместо MOV, чтобы получить адрес. (И все же масштабируйте ваш индекс, потому что элементы имеют длину 4 байта. В противном случае вы создаете 4-байтовое хранилище со смещением в 1 байт, которое частично перекрывает два float элемента price[].)

...