Имеется такая структура: Код (Text): TStars STRUCT ColorR GLfloat ? ColorG GLfloat ? ptSize GLfloat ? X GLfloat StarsCount dup(?) Y GLfloat StarsCount dup(?) Z GLfloat StarsCount dup(?) Speed GLfloat 0.05f TStars ends как мне обратиться, например, к Z[10]? Мне нужно сделать так: Код (Text): fld TStars.Z[ebx] fadd TStars.Speed fstp TStars.Z[ebx] где ebx счётчик цикла
скорей всего одной иструкции не хватит. нужно что то тип такого: Код (Text): lea edi,[z] ;загрузка адресса первого элемента массива fld TStars.Z[edi + sizeof(GLfloat)*ebx] fadd TStars.Speed fstp TStars.Z[edi + sizeof(GLfloat)*ebx] Размер GLfloat должен быть одним из 1,2,4,8.
Переписал так: Код (Text): lea eax, GLfloat PTR TStars.Speed lea edi, GLfloat PTR TStars.Z fld TStars.Z[edi + sizeof(GLfloat) * ebx] fadd GLfloat PTR [eax] fstp TStars.Z[edi + sizeof(GLfloat) * ebx] в IDA вижу такой код: Код (Text): loc_4012CA: ; CODE XREF: sub_4012AB+3Cj lea eax, ds:2A30h lea edi, ds:2328h fld dword ptr [edi+ebx*4+2328h] fadd dword ptr [eax] fstp dword ptr [edi+ebx*4+2328h] непонятно, почему ссылка на структуру идёт прямым адресом
При просмотре IDA-ой я не нашёл саму структуру ни чего либо напоминающего, поэтому и вопрос о прямой ссылке.
dsoft не правда - правильно fld TStars.Z[sizeof(GLfloat) * ebx] которое скомпилится в fld dword ptr [ebx*4+2328h] где адрес структуры уже забит а из-за добавления lea edi, GLfloat PTR TStars.Z и [edi + ...] получается что адрес структуры прибавляется дважды или если хочешь адресацию только через регистр то: lea edi, GLfloat PTR TStars.Z fld [edi + sizeof(GLfloat) * ebx] уже без имени структуры и поля. Этот вариант обязателен если структура TStars локальная (расположена в стеке) Для глобальной структуры выбор первого или второго варианта адресации дело вкуса - [извращение] второй иногда может сэкономить несколько байт за счёт сокращения длины команд fld, fstp ) [/извращение] Но не оба сразу же их применять в одной команде )
Код (Text): some TStars <> lea ESI,some mov EBX,10 mov byte ptr ((TStars ptr [SI]).z)[EBX],AL идея понятна ??
Код (Text): fld TStars.Z[sizeof(GLfloat) * ebx] семантическая бредятина после имени структуры должен быть ptr и адрес экземпляра (пусть косвенный [ebx]) дальше точка и тд
Код у тебя правильный только для локальных структур, когда в качестве базы не явно будет ebp. Но лучше чтобы у переменной было имя отличное от имени структуры. Например: Код (Text): LOCAL Stars:TStars ;локальное имя Stars ... fld Stars.Z[ebx] fadd Stars.Speed fstp Stars.Z[ebx] Для обращения к глобальной структуре в твоём коде не хватает базы Код (Text): mov edi,offset Stars ;Stars глобальная структура, edi - база fld TStars.Z[ebx][edi] fadd TStars.Speed[edi] fstp TStars.Z[ebx][edi] На счет масштабирования с ebx уже сам думай.
Так и есть, из-за чего я тормознул. Не уверен, ассемблер для меня не основной язык. С масштабированием всё понятно, этому меня приучил Паскаль. А всё таки может All подскажет почему я не нахожу структуру в IDA-е? Объявлена она у меня глобально.
Скорее всего, для кого-то это прозвучит бредом, но мне взбрело в голову переложить код из Паскаля на Ассемблер, и в данном случае это: Код (Text): const StarsCount = 450; type TStars = record ColorR, ColorG, Size, X, Y, Z : array[0..StarsCount - 1] of GLfloat; Speed : GLfloat; end; for I := 0 to StarsCount - 1 do begin with Stars do begin glColor3f(ColorR[i], ColorG[i], 1.0); glPointSize(Size[i]); Z[i] := Z[i] + Speed; glBegin(GL_POINTS); glVertex3f(X[i], Y[i], Z[i]); glEnd; if Z[i] > -1 then begin X[i] := RandFloat(16) - 8; Y[i] := RandFloat(16) - 8; Z[i] := Random(10) - 25; end; end; end;
Попутно возник ещё вопрос. После указания Код (Text): Stars TStars <> хоть локально, хоть глобально, exe файл вырастает на размер структуры. Можно ли как-нибудь создавать структуру динамически, чтобы не увеличивать размер файла?
Можно получить память динамически: LocalAlloc, VirtualAlloc. Код (Text): push sizeof (TStars) ; push LMEM_FIXED call LocalAlloc ; в еах у тебя теперь указатель на память ;когда память уже будет не нужна, красиво будет ее освободить ). push eax call LocalFree
Все переменные, структуры, массивы в секции .data? не увеличивают размер файла, в нём хранятся только инициализированные из секции .data Про Local и GlobalAlloc давно пора забыть это оставлено для совместимости с win16, а уже win64 идёт полным ходом Вместо них HeapAlloc для мелких блоков, а VirtualAlloc для крупных (она значительно медленнее HeapAlloc и выделяет целые страницы памяти). И набери в поиске по форуму эти функции узнаешь много интересного.
XshStasX MSDN 2008 SP1: LocalAlloc Function ... Note The local functions are slower than other memory management functions and do not provide as many features. Therefore, new applications should use the heap functions. ... Remarks Windows memory management does not provide a separate local heap and global heap. Правда есть скользкий нюанс из-за которого их окончательно так и не перенесли в разряд Obsolete Functions. Буфер обмена (Clipboard) для совместимости с win16 до сих пор требует использования GlobalAlloc, GlobalLock, хотя ничего не мешало предусмотреть альтернативный вариант совместимый на уровне "внутренностей" но с нормальными API. Появилось ли это хотя-бы в win64 не знаю не разбирался.
Что значит, плохо знать язык. Вся ошибка была в этом: Код (Text): .data? Stars TStars <?> И зачем я ставил вопрос, сам не пойму. Спасибо за подсказку про заём памяти.