Помогите разобраться с 2мя функциями. Ниже представлен исходник с комментариями(в них указаны проблемы). ;------------------------------------------------------- ;Устанавливает текущее положение курсора в консоле ;На вход: hOutPut - хэндл вывода консоли, DH - столбец, DL - строка,структура COORD(dwCurPos) ;Выход: ничего ;Процедуры: никаких ;------------------------------------------------------- SetCursorPosition proc c hOutPutWORD LOCAL dwCurPos :COORD ;Виндовая структура push eax push ebx push ecx push edx mov ebx,[ebp+dwCurPos] ; mov [ebx].x,dl ;!!!!! Проблема. Не может определить x! ; mov [ebx].y,dh ;!!!!! Проблема. Не может определить y! invoke SetConsoleCursorPosition,hOutPut,addr dwCurPos pop edx pop ecx pop ebx pop eax ret SetCursorPosition endp ;------------------------------------------------------- ;Выводит символ на консоль ;На вход: hOutPut - хэндл вывода консоли,dl - код символа ;Выход: ничего ;Процедуры: никаких ;------------------------------------------------------- WriteChar proc c hOutPutWORD ;uses eax,ebx,ecx,edx ;автоматический пролог и эпилог, формируемый транслятором !!!!Проблема. Почему не работает? Пришлось заменить push/pop вызовами. LOCAL CharCode :BYTE ;локальная переменная, для хранения полученного кода симвсимвола LOCAL nWritten WORD push eax push ebx push ecx push edx ;------------ПРЕОБРАЗОВАНИЕ КОДА СИМВОЛА---------------- ; mov bx,dx cmp dl,0Ah jae HEX_LETTER add dl,30h jmp DIGIT HEX_LETTER: add dl,37h DIGIT: mov CharCode,dl ;------------------------------------------------------- invoke WriteConsole,hOutPut,addr CharCode,1,nWritten,NULL ;!!!Проблема. ;В процессе работы возникает следуещее: ;In process: 0x000001E8 ;In thread: 0x000001D8 ;*** Exception raised at address: 0x793BC3DD ;*** Access violation ;*** Writing attempt to address: 0xA. ; Почему? pop edx pop ecx pop ebx pop eax ret WriteChar endp Анализируя свой код, у меня появилось несколько вопросов: 1.)Как сохранять значения в локальных переменных? 2.)Как создавать экземпляр структуры(локальный для функции) проинициализированной сразу в LOCAL,а затем изменять значения полей этого экз.? 3.)Почему не работает директива uses? 4.)Когда использовать каждую из команд(в каких местах какие нужны) lea,offset,addr? Имею в виду локальные переменные. И вообще обязательно все переменные объявлять в секции .data, чтобы потом можно было менять их значения? Например, мне нужна какая-то переменная для расчета(промежуточная), зачем мне ее объявлять в секции .data? 5.)Как правильно импортировать структуры из inc, lib? Может я не правильно это сделал с виндовой структурой - COORD?
Если кто не полениться ответить, скиньте правильный вариант функций с комментариями или на крайний случай объясните в чем я не прав. P.S.Сильно не ругать - я начинающий.
пишется ч-з пробел Используй ф-ю из библиотеки masm32.lib (там и сорцы есть) StdOut, с ней удобней Анализируя свой код, у меня появилось несколько вопросов: 1.)Как сохранять значения в локальных переменных? 2.)Как создавать экземпляр структуры(локальный для функции) проинициализированной сразу в LOCAL,а затем изменять значения полей этого экз.? test proc uses ebx esi edi lpszBuffer:dword local x:dword local z:SOME_STRUCTURE mov x,eax lea edi,z assume edi:ptr SOME_STRUCTURE mov [edi].element,ebx assume edi:nothing ret test endp 4.)Когда использовать каждую из команд(в каких местах какие нужны) lea,offset,addr? Имею в виду локальные переменные. И вообще обязательно все переменные объявлять в секции .data, чтобы потом можно было менять их значения? Например, мне нужна какая-то переменная для расчета(промежуточная), зачем мне ее объявлять в секции .data? Локальные переменные работают в пределах процедуры, переменные объявленые в секциях .data, .data? - в пределах процесса
Как сохранять значения в локальных переменных? test proc uses edi param1:dword local x:dword local z:POINT ; сохранение в локальную переменную mov dword ptr [x],01234h ; очистка структуры lea edi,[z] xor al,al mov ecx,sizeof POINT rep stosb ; запись в структуру lea eax,[z] mov (POINT ptr [z]).x,1 mov (POINT ptr [x]).y,2 ; ещё один способ записи в структуру mov [z].x,1 mov [z].x,2 ; и ещё один lea eax,[z] assume eax:ptr POINT mov [eax].x,1 assume eax:nothing ret test endp Когда использовать каждую из команд(в каких местах какие нужны) lea,offset,addr? Имею в виду локальные переменные. для структур, в основном, а также для получения адреса переменной И вообще обязательно все переменные объявлять в секции .data, чтобы потом можно было менять их значения? нет, не обязательно Например, мне нужна какая-то переменная для расчета(промежуточная), зачем мне ее объявлять в секции .data? поэтому не обязательно
С MASMом есть фишка - если определена структура с помощью директивы STRUC но нигде не определено ни одной переменой с типом данной структуры то при использовании полей структуры в косвенной адресации обязательны конструкции вида (StrucName PTR[EBX]).FieldName
Нельзя получить адрес локальной переменной с помощью ADDR!!! Потому что например LOCAL CharCode:BYTE превращается в CharCode EQU BYTE PTR SS:[EBP+0Ah], а ADDR не может вычеслить EBP+0Ah и возвращает просто 0Ah,что и приводит к GPF.в таких случаях нужно писать так LEA EAX,CharCode;EAX=EBP+0Ah INVOKE WriteConsole hOutPut,EAX,1... и все будет в порядке!!!