Есть вопрос?
Зайди на форум

Поиск на сайте: Advanced

Denix - новый дистрибутив Linux. Русификация Ubuntu и установка кодеков

dkws.org.ua
Форум сайта dkws.org.ua
 
Главная    ТемыТемы    АльбомАльбом    РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Masm32 для въедливых

 
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> Программирование/C/C++
 
Автор Сообщение
DmitryNew

Новенький


Зарегистрирован: 29.01.2011
Сообщения: 19
Откуда: Киев

СообщениеДобавлено: Сб Сен 12, 2015 7:25 am    Заголовок сообщения: Masm32 для въедливых
Ответить с цитатой

Здравствуйте!
Вопрос не по С, но возможно кто то подскажет?
Имеем простую программу на ассемблере masm32 для вывода цифры на экран.
.386
.model flat,stdcall
option casemap:none
include C:\masm32\include\kernel32.inc
include C:\masm32\include\windows.inc
include C:\masm32\include\user32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
BSIZE equ 16
.data
Day DWORD 3
ifmt BYTE "%d", 0
buf BYTE BSIZE dup(0)
stdout DWORD ?
cWritten DWORD ?
.code
start:
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov stdout, eax
invoke wsprintf, ADDR buf, ADDR ifmt, Day
invoke WriteConsoleA, stdout, ADDR buf,\
10 , ADDR cWritten, NULL
invoke ExitProcess , 0
end start
Всё корректно отрабатывает. Но если заменить Day DWORD 3 на Day WORD 3 цифра не распечатывается. Я понимаю что стандартный тип данных параметра процедуры двойное слово. Но и после замены wsprintf отрабатывает и записыват в память 33h т.е. 3 для вывода в консоль.
А параметр WriteConsoleA --> ADDR buf не двойное слово.
Что не правильно если заменить Day DWORD 3 на Day WORD 3?
Согласен что большого практического значения вопрос не имеет но не хочется иметь пробелы в понимании.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DmitryNew

Новенький


Зарегистрирован: 29.01.2011
Сообщения: 19
Откуда: Киев

СообщениеДобавлено: Вс Сен 13, 2015 7:12 am    Заголовок сообщения:
Ответить с цитатой

Полагаю что это связано с тем что wsprintf хоть и отработала но неправильно из за неправильного типа данных параметра. Но окончательной уверенности у меня нет и вот почему:
Имеем простую программу для чтения и вывода в консоль файла
.386
.model flat, stdcall
option casemap: none
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\user32.inc
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\kernel32.lib
.data
fName1 BYTE "datas", 0
fHandle1 DWORD ?
stdout DWORD ?
cRead DWORD ?
cWritten DWORD ?
buf4 DWORD 4 dup(?)
buf2 WORD 8 dup(?)
;buf1 BYTE 4 dup(?)
buf1 BYTE 5 dup(?)
;buf1 BYTE 6 dup(?)
;buf1 BYTE 7 dup(?)
;buf1 BYTE 8 dup(?)
;buf1 BYTE 9 dup(?)
;buf1 BYTE 10 dup(?)
;nLine_error BYTE 0dh, 0ah
.code
start:
invoke GetStdHandle, STD_OUTPUT_HANDLE
mov stdout, eax
invoke CreateFile, ADDR fName1, GENERIC_READ,\
0, NULL, OPEN_EXISTING,\
FILE_ATTRIBUTE_NORMAL, 0
mov fHandle1, eax
invoke ReadFile, fHandle1, ADDR buf1, 8,\
ADDR cRead, NULL
invoke WriteConsoleA, stdout, ADDR buf1,\
6, ADDR cWritten, NULL
invoke CloseHandle, fHandle1
invoke ExitProcess, 0
end start
В файле datas записано 64h 61h 74h 61h т.е. просто data
В том виде как выше программа корректно отрабатыват. Но стоит раскомментировать строку nLine_error BYTE 0dh, 0ah как
слово data перестаёт выводится в консоль. Но если при этом еще заменить buf1 BYTE 5 dup(?) на buf1 BYTE 4 dup(?) или buf1 BYTE 6 dup(?) опять всё корректно! Вот такое нехорошее "чудо". И абсолютно не понятно как неиспользуемая метка может на что влиять (nLine_error BYTE 0dh, 0ah).
Из этого всего делаю вывод что и с WriteConsoleA возможны какие то проблемы.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DmitryNew

Новенький


Зарегистрирован: 29.01.2011
Сообщения: 19
Откуда: Киев

СообщениеДобавлено: Вс Сен 13, 2015 8:06 am    Заголовок сообщения:
Ответить с цитатой

Со вторым вопросом разобрался -- вспомнил что ассемблер не язык высокого уровня. Напечатать нужно 4 символа а не 6 (invoke WriteConsoleA, stdout, ADDR buf1, 6[здесь], ADDR cWritten, NULL ). Мой вывод "убил" BYTE 0dh.
Но что не так программой 1?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
DmitryNew

Новенький


Зарегистрирован: 29.01.2011
Сообщения: 19
Откуда: Киев

СообщениеДобавлено: Вс Сен 13, 2015 9:14 am    Заголовок сообщения:
Ответить с цитатой

Сделал сам:
Day WORD 3

Вариант 1)
xor eax, eax
mov ax, Day
invoke wsprintf, ADDR buf, ADDR ifmt, eax

Вариант 2)
mov ax, 0
push ax
mov ax, Day
push ax
mov eax, offset ifmt
push eax
mov eax, offset buf
push eax
call wsprintf

Вариант 3)
mov ax, 0
push ax
invoke wsprintf, ADDR buf, ADDR ifmt, word ptr Day
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему Ответить на тему    Список форумов dkws.org.ua -> Программирование/C/C++ Часовой пояс: GMT
Страница 1 из 1
 Главная страница сайта
 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
© Колисниченко Денис