2015-06-16 3 views
7

Итак, я научил себя x86 Assembly a while back и просто играл с inline Assembly на C++.Изменение значений массива в функции - Встроенная сборка

Итак, что я хочу сделать, это параметры функций, передать в массив, индекс (unsigned int) и число. С помощью сборки он затем изменит значение в этой ячейке памяти массива на переданное значение. Таким образом, код выглядит так.

inline void Set(int pArray[], unsigned int pIndex, int pNum) { 
    __asm { 
     mov ebx, pIndex 
     mov eax, 4 
     mul ebx 
     mov ebx, pNum 

     lea edi, pArray 
     mov [ edi + eax ], ebx 
    } 
} 

int main() { 
    int myArray[ 5 ] = { 1, 2, 3, 4, 5 }; 
    Set(myArray, 2, 7); 
    std::cout << myArray[ 2 ] << std::endl; 
} 

Таким образом, код должен загрузить начало адреса массива, получить индекс и умножить на 4, так что ячейка памяти перемещается с тем, что многие байт, и это изменяет его значение, переданное в. Однако, когда я это делаю, значение остается неизменным. Почему это? Что происходит не так?

+2

Возможно, вам захочется «mov edi, pArray», иначе вы можете загрузить адрес переменной аргумента, а не там, где он указывает. Возможно, вам захочется научить себя использовать отладчик тоже :) – Jester

+1

Yup. Это была проблема. Я написал это из функции, изначально, где массив мог быть доступен в его области, поэтому он работал тогда, но когда он был инкапсулирован в функцию, он переставал работать, поэтому имеет смысл понять, почему я должен использовать «mov», а не «Леа». Спасибо :-) – CMilby

ответ

1

lea означает «Загрузить эффективный адрес», ваш lea помещает адрес аргумента. То, что вы имеете в виду, lea edi, [pArray]

Однако есть еще две вещи: 1) Вам не нужно умножаться на четыре. Вы можете сделать lea edi, [pArray + 4*ebx] Поскольку режим адресации «индексный байт» позволяет вам умножить на 4 и добавить немедленный адрес.

2) Вы принимаете 32 бита. Какой компьютер вы используете, что в середине 2015 года все еще работает в 32-битном режиме?

Я ржавый на сборке синтаксиса. Могу ли я рекомендовать вам изучить интеграцию ассемблера и кода на C++ в GCC? https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

+0

Для 1, lea edi, [pArray + 4 * ebx] 'не изменяет значение. И для 2, это большой вопрос. Я работаю в Visual Studio Professional 2010 и не разрешу использовать 64-разрядные регистры. Я сделал это первоначально с 64-битными регистрами, но продолжал получать ошибку C2415. – CMilby

+0

Нет необходимости загружать эффективный адрес или использовать инструкцию умножения. Проверьте, что компилятор GCC исследователь показывает: http://goo.gl/njHPU3 Просто используйте "масштабный индекс байт" адресацию, как это: 'мы [RDI + RSi * 4], edx' Где RDI является массив базового адреса в соглашении вызова linux, rsi - это индексный параметр, а edx - значение – EdMaster

Смежные вопросы