Member 13932705 Ответов: 2

Как установить регистр eax в встроенной сборке C++


eax и ebx-это 32-битные регистры. массивы a[] и b[] содержат 4 символа и 32 бита данных. я могу отдельно установить каждый индекс массива в каждом регистре,например mov eax, a[1].
но я хочу установить все 4 символа массива 'a' в регистр eax. главное - это последовательность действий. Я хочу установить эти два регистра без каких-либо изменений в последовательности содержимого массивов. например, первый массив-это a[0]='a',a[1]='b',a[2]='c',a[3]='d' , а регистр eax должен быть как "abcd". как я могу это сделать?

Что я уже пробовал:

<pre lang="c++">
int _tmain()
{
char b[4],a[4];
b[0]='A',b[1]='T',b[2]='C',b[3]='G';
a[0]='A',a[1]='T',a[2]='C',a[3]='G';
__asm
{
    movzx eax,a[1]  //here i want to load all 4 char of a
    movzx ebx,b[1]  //here i want to load all 4 char of b 
}
getchar();
return 0;
}

Richard MacCutchan

Почему? Как только этот код будет передан, регистры будут использоваться для других целей, как это решит компилятор.

2 Ответов

Рейтинг:
2

Patrice T

Цитата:
eax и ebx-это 32-битные регистры. массивы a[] и b[] содержат 4 символа и 32 бита данных. я могу отдельно установить каждый индекс массива в каждом регистре,например mov eax, a[1].

прежде всего, вы должны попытаться заменить
movzx eax,a[1]  //here i want to load all 4 char of a
movzx ebx,b[1]  //here i want to load all 4 char of b

около
movzx eax,a[0]  //here i want to load all 4 char of a
movzx ebx,b[0]  //here i want to load all 4 char of b

потому что массивы основаны на 0 в C++.
Цитата:
Как установить регистр eax в встроенной сборке C++

в противном случае, в чем ваша проблема с этим кодом ?


Рейтинг:
13

Jochen Arndt

Компилятор знает, что массивы имеют тип char, и генерирует

MOV EAX,BYTE PTR [addr]

Если вы хотите загрузить 32-битное значение из байтового массива, скажите компилятору, что он должен загрузить 32-битные слова (непроверенные, но должны это сделать):
__asm
{
    mov eax,DWORD PTR [a]
    mov ebx,DWORD PTR [b]
}

Или бросить char массив указателей на DWORD указатели:
uint32_t* a32 = reinterpret_cast<uint32_t*>(a);
uint32_t* b32 = reinterpret_cast<uint32_t*>(b);
__asm
{
    mov eax,a32[0]
    mov ebx,b32[0]
}
Обратите внимание, что в обоих случаях использование MOVZX не имеет смысла, когда источник и пункт назначения имеют одинаковый размер.

[РЕДАКТИРОВАТЬ]
Испытали его тем временем. С помощью DWORD PTR работает так, как ожидалось, при использовании приведенного указателя не работает (загружает регистр с адресом a32 resp. b32).
[/РЕДАКТИРОВАТЬ]