Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.08.2012, 11:14   #1
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,603
По умолчанию Разбор кода инициализирующего OpenGL

Приветствую всех форумчан. Вопрос ради спортивного интереса. В примерах FASM есть приложение использующее OpenGL. Инициализация проходит следующим образом
Код:
 invoke  GetDC,[hwnd]
        mov     [hdc],eax
        mov     edi,pfd
        mov     ecx,sizeof.PIXELFORMATDESCRIPTOR shr 2
        xor     eax,eax
        rep     stosd
        mov     [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
        mov     [pfd.nVersion],1
        mov     [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+PFD_DRAW_TO_WINDOW
        mov     [pfd.iLayerType],PFD_MAIN_PLANE
        mov     [pfd.iPixelType],PFD_TYPE_RGBA
        mov     [pfd.cColorBits],16
        mov     [pfd.cDepthBits],16
        mov     [pfd.cAccumBits],0
        mov     [pfd.cStencilBits],0
        invoke  ChoosePixelFormat,[hdc],pfd
        invoke  SetPixelFormat,[hdc],eax,pfd
        invoke  wglCreateContext,[hdc]
        mov     [hrc],eax
        invoke  wglMakeCurrent,[hdc],[hrc]
        invoke  GetClientRect,[hwnd],rc
        invoke  glViewport,0,0,[rc.right],[rc.bottom]
        invoke  GetTickCount
        mov     [clock],eax
        xor     eax,eax
        jmp     .finish
Что делают эти строки
Код:
invoke  GetDC,[hwnd]
        mov     [hdc],eax
        mov     edi,pfd
        mov     ecx,sizeof.PIXELFORMATDESCRIPTOR shr 2
        xor     eax,eax
        rep     stosd
Попробую описать по очереди
Первые две получает дескриптор формы.
Третья заносит в регистр edi указатель на структуру pfd
Четвертая. Вот тут сомневаюсь. Я думаю, что размер структуры PIXELFORMATDESCRIPTOR делится на два сохраняется в ecx, если так, то зачем?
В пятой ecx присваивается 0.
rep повторяет команду stosd столько раз, сколько будет если размер структуры pfd поделить на 2. Записывая в каждые 4 байта 0. После углубленного письменного анализа в голову пришла идея, что этот код тупо заполняет нулями структуры pfd. Уже лучше. Тогда не пойму зачем размер структуры делить на 2? И за одно, раз так получилось, спрошу принцип работы stosd.
Цитата:
Переписывает содержимое ЕАХ в ячейку памяти с адресом ES: (E)DI, после чего прибавляет 4 к (E)DI, если флаг D опущен, и вычитает 4, если D поднят.
В третей строке адрес присваивается регистру edi, тогда каким боком в цитате написано ESE)DI? Как и когда используется ES? Напомню, что еще интересует: зачем размер структуры делить на 2
Заранее благодарен.
P.S. Теперь непонятные места буду именно так разбирать, только на листочке.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 20.08.2012, 11:45   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Делится не на 2 а на 4 (два сдвига вправо). А делается это потому что в дальнейшем исползуется инструкция stosD, т.е. записываем по 4 байта за раз. Кстати, этот фокус прокатит *только* для структур, чей размер кратен 4 байтам.

ES используется либо задав явно префикс ES: либо (как в данном случае) просто сказано, что инструкция работает *всегда* через ES.
waleri вне форума Ответить с цитированием
Старый 20.08.2012, 12:01   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,162
По умолчанию

Цитата:
Что делают эти строки?
Обнуляют структуру pfd, в Windows ES=CS=DS=SS поэтому о значении в сегментных регистрах не беспокоятся, если бы заполнение шло командами STOSB тогда делить размер структуры на 4 было бы не нужно, а здесь сразу по 4 байта одной командой, что в 4 раза быстрее

Последний раз редактировалось Mikl___; 20.08.2012 в 12:06.
Mikl___ вне форума Ответить с цитированием
Старый 20.08.2012, 12:08   #4
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,603
По умолчанию

Цитата:
ES используется либо задав явно префикс ES: либо (как в данном случае) просто сказано, что инструкция работает *всегда* через ES.
Инструкция сама его использует? Я к нему не прикасаюсь. Не могу понять: зачем там нужен этот регистр, если для адресации используется edi?

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 20.08.2012, 12:15   #5
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от _PROGRAMM_ Посмотреть сообщение
Инструкция сама его использует? Я к нему не прикасаюсь. Не могу понять: зачем там нужен этот регистр, если для адресации используется edi?
это вы спросите у Intel - они так сделали, что stosb/w/d пишет в ES:EDI
Если знать историю будет понятно зачем, иначе как бы вы скоопировали данные из одного сегмента в другой? LODS работает по DS STOS работает по ES.
waleri вне форума Ответить с цитированием
Старый 20.08.2012, 12:19   #6
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,603
По умолчанию

Ясно. Спасибо за помощь.
P.S. Не разрешают мне еще Вам один + ставить.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 21.08.2012, 04:29   #7
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,162
По умолчанию

_PROGRAMM_
на самом деле строки
Код:
        mov     edi,pfd
        mov     ecx,sizeof.PIXELFORMATDESCRIPTOR shr 2
        xor     eax,eax
        rep     stosd
        mov     [pfd.nSize],sizeof.PIXELFORMATDESCRIPTOR
        mov     [pfd.nVersion],1
        mov     [pfd.dwFlags],PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+ PFD_DRAW_TO_WINDOW
        mov     [pfd.iLayerType],PFD_MAIN_PLANE
        mov     [pfd.iPixelType],PFD_TYPE_RGBA
        mov     [pfd.cColorBits],16
        mov     [pfd.cDepthBits],16
        mov     [pfd.cAccumBits],0
        mov     [pfd.cStencilBits],0
лишние, так как проинициализировать структуру PIXELFORMATDESCRIPTOR можно было в данных
Код:
pfd:
 dw 40  ; nSize
 dw 1   ; nVersion
 dd PFD_SUPPORT_OPENGL+PFD_DOUBLEBUFFER+ PFD_DRAW_TO_WINDOW  ; dwFlags
 db 0   ; iPixelType
 db 32
 db 0			; cRedBits
 db 0			; cRedShift
 db 0			; cGreenBits
 db 0			; cGreenShift
 db 0			; cBlueBits
 db 0			; cBlueShift
 db 0			; cAlphaBits
 db 0			; cAlphaShift
 db 0			; cAccumBits
 db 0			; cAccumRedBits
 db 0			; cAccumGreenBits
 db 0			; cAccumBlueBits
 db 0			; cAccumAlphaBits
 db 16                  ; cDepthBits
 db 0			; cStencilBits
 db 0			; cAuxBuffers
 db 0			; iLayerType
 db 0			; bReserved
 dd 0			; dwLayerMask
 dd 0			; dwVisibleMask
 dd 0			; dwDamageMask
Mikl___ вне форума Ответить с цитированием
Старый 21.08.2012, 11:02   #8
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,493
По умолчанию

Цитата:
Сообщение от _PROGRAMM_ Посмотреть сообщение
Ясно. Спасибо за помощь.
P.S. Не разрешают мне еще Вам один + ставить.
Ну, это логично, а то я бы себе сделал второй акаунт и поставил бы себе стопитьсот лайков
waleri вне форума Ответить с цитированием
Старый 22.08.2012, 09:55   #9
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,603
По умолчанию

Цитата:
лишние, так как проинициализировать структуру PIXELFORMATDESCRIPTOR можно было в данных
Я понимаю. Просто меня заинтересовал сам код.

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Старый 17.11.2012, 20:05   #10
_PROGRAMM_
Участник клуба
 
Аватар для _PROGRAMM_
 
Регистрация: 30.07.2009
Сообщений: 1,603
По умолчанию

Вспомнил, что была у меня такая тема, поэтому не стал создавать новую. Они тематически похожи с моим вопросом. Тоже инициализация, только glut.
Есть такой код.
Код:
format PE GUI 4.0
entry start


include '%fasminc%/win32ax.inc'
include '%fasminc%/OpenGL.inc'

section '.text' code executable writeable
         start:
         push   dword esp+8
         lea    eax, [esp+8]
         push   eax
         call   [glutInit]
         invoke glutInitWindowSize,400,400
         invoke glutInitWindowPosition,100,100
         invoke glutInitDisplayMode,2
         invoke glutCreateWindow,'Test Asm OpenGL';
         invoke MessageBox,0,0,0,0
         invoke Sleep,5000
         invoke ExitProcess,0
;section '.data' data readable writeable

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          gdi,'GDI32.DLL',\
          glut,'GLUT32.DLL',\
          msvcrt,'msvcrt.dll'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         GetTickCount,'GetTickCount',\
         ExitProcess,'ExitProcess',\
         Sleep,'Sleep'

  import user,\
         MessageBox,'MessageBoxA',\
         RegisterClass,'RegisterClassA',\
         CreateWindowEx,'CreateWindowExA',\
         DefWindowProc,'DefWindowProcA',\
         GetMessage,'GetMessageA',\
         TranslateMessage,'TranslateMessage',\
         DispatchMessage,'DispatchMessageA',\
         LoadCursor,'LoadCursorA',\
         LoadIcon,'LoadIconA',\
         GetClientRect,'GetClientRect',\
         GetDC,'GetDC',\
         ReleaseDC,'ReleaseDC',\
         PostQuitMessage,'PostQuitMessage',\
         wsprintf,'wsprintfA',\
         GetAsyncKeyState,'GetAsyncKeyState',\
         GetSystemMetrics,'GetSystemMetrics',\
         ChangeDisplaySettings,'ChangeDisplaySettingsA'



  import gdi,\
         ChoosePixelFormat,'ChoosePixelFormat',\
         SetPixelFormat,'SetPixelFormat',\
         SwapBuffers,'SwapBuffers'

  import glut,\
         glutInit ,'glutInit',\
         glutInitWindowSize,'glutInitWindowSize',\
         glutInitWindowPosition,'glutInitWindowPosition',\
         glutInitDisplayMode,'glutInitDisplayMode',\
         glutCreateWindow,'glutCreateWindow',\
         <........>
         glGetMinmaxParameterfv,'glGetMinmaxParameterfv'
Описание функций больше чем кода, но не об этом. В общем есть функция инициализирующая glut - это glutInit. Так вот. Программа вылетает на ее вызове. В то, что находится в коде, наверно, ошибочно. Я его стянул из листинга под NASM(хотя у них с fasm'ом синтаксис очень схож). О их задаче только что прочитал в интернете, а как правильно достать эти переменные из стека и использовать?

В мире нет вечных двигателей, зато есть вечные тормоза...

Блог
_PROGRAMM_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разбор кода CSharp zxzLeejacKzxz C# (си шарп) 4 13.06.2012 07:25
Разбор кода Arhit Помощь студентам 3 22.01.2012 16:34
Разбор кода Delphi cv0l04b Помощь студентам 3 07.01.2012 13:39
Разбор куска кода. Alexcomeback Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 2 05.04.2011 18:14
Разбор кода. С++ TIT0 Помощь студентам 0 27.12.2010 11:17