Некоторые встроенные вопросы ассемблера - PullRequest
1 голос
/ 06 ноября 2010

Я уже задавал подобный вопрос здесь, но я все еще получаю некоторые ошибки, поэтому я надеюсь, что вы могли бы сказать мне, что я делаю неправильно.Просто знайте, что я знаю ассемблер, и я сделал несколько проектов на ассемблере 8051, и даже это не то же самое, что близко к x86 asm.

Есть блок кода, который я пробовал в VC ++ 2010 Express (я пытаюсь получить информацию из инструкции CPUID): `

int main()
{
char a[17]; //containing array for the CPUID string
a[16] = '\0'; //null termination for the std::cout
void *b=&a[0]; 
int c=0; //predefined value which need to be loaded into eax before cpuid

_asm
{
    mov eax,c;
    cpuid;
    mov [b],eax;
    mov [b+4],ebx;
    mov [b+8],ecx;
    mov [b+12],edx;
}
std::cout<<a;
}`

Итак, чтобы быстро подвести итог, я попытался создать пустой указатель на первый элемент массива, а затем с помощью косвенной адресации просто переместить значения из регистров.Но этот подход дает мне «стек вокруг переменной b - поврежденная ошибка времени выполнения», но я не знаю почему.

Пожалуйста, помогите.Благодарю.И это только для учебных целей, я знаю, что есть функции для CPUID ....

РЕДАКТИРОВАТЬ: Кроме того, как вы можете использовать прямую адресацию в x86 VC ++ 2010 встроенный ассемблер?Я имею в виду общий синтаксис для немедленной загрузки числа в 8051 mov src,#number, но в VC ++ asm его mov dest,number без знака #.Так как же сказать компилятору, что вы хотите напрямую обращаться к ячейке памяти по адресу x?

Ответы [ 2 ]

6 голосов
/ 06 ноября 2010

Причина, по которой ваш стек поврежден, заключается в том, что вы храните значение eax в b.Затем сохранение значения ebx в ячейке памяти b+4 и т. Д. Синтаксис встроенного ассемблера [b+4] эквивалентен выражению C ++ &(b+4), если b был указателем байта.

Это можно увидеть, если вы посмотрите b и пошагово.Как только вы выполните mov [b],eax, значение b изменится.

Одним из способов решения проблемы является загрузка значения b в регистр индекса и использование индексированной адресации:

mov edi,[b]
mov [edi],eax
mov [edi+4],ebx
mov [edi+8],ecx
mov [edi+12],edx

Вам вообще не нужно b, чтобы удерживать указатель на a.Вы можете загрузить индексный регистр напрямую с помощью инструкции lea (загрузить эффективный адрес):

lea edi,a
mov [edi],eax
... etc ...

Если вы возитесь с встроенным ассемблером, неплохо было бы открыть окно регистров в отладчике иПосмотрите, как все меняется, когда вы пошаговые.

Вы также можете напрямую обратиться к памяти:

mov dword ptr a,eax
mov dword ptr a+4,ebx
... etc ...

Однако для такой прямой адресации требуется больше байтов кода, чем для индексированной адресации впредыдущий пример.

Я думаю, что выше, с инструкцией lea (Load Effective Address) и прямой адресацией, которую я показал, отвечает на ваш последний вопрос.

0 голосов
/ 20 июля 2011

Советы по открытию окна «Регистры» в отладчике следят за тем, как что-то измениться не будет работать в VC ++ 2010 Express.

Вы можете быть удивлены так же, как и я, узнав, что VC ++ 2010 Express пропускает окно регистров. Это особенно удивительно, так как наступает разборка.

Единственный известный мне обходной путь - это открыть окно наблюдения и ввести имена регистров в поле Имя. Введите EAX EBX ECX EDX ESI EDI EIP ESP EBP EFL и CS DS ES SS FS GS, если хотите

ST1 ST2 ST3 ST4 ST5 ST6 ST7 также работают в окне часов.

Возможно, вы также захотите установить значение в шестнадцатеричное значение, щелкнув правой кнопкой мыши в окне Watch и выбрав шестнадцатеричное отображение.

...