Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для Windows/Dos > Как создать консольное приложение Windows x64?


Автор: ТарасАтавин 3.9.2013, 09:49
Я начинающий компиляторописака. С чего начинать создание приложения на ASM и в опкоде и изучение вопроса? Надо ли вообще раскладывать регистры по сегментам и как? Как это выглядит в коде исполняемого файла? Каким образом возвращается значение при завершении приложения? Как получить доступ к параметрам функции 
Код
int main (int argc, char *argv[])
 (содержащей точку входа)? Как указать точку входа на ассемблере и в коде исполняемого файла? Как организован стек в Windows-приложении x64? Как на низком уровне организован консольный ввод/вывод? Надо ли специально регистрировать экспортируемые функции в GetProcAdress? И как?

Автор: _zorn_ 3.9.2013, 10:08
Цитата(ТарасАтавин @  3.9.2013,  17:49 Найти цитируемый пост)
(содержащей точку входа)? 

Начнем с того что это не так. main - это библиотечная функция, которая вызывается после всяких инициализаций.
Консольный ввод/вывод так же выполняется библиотечными функциями обертками, которые в свою очередь могут использовать WinAPi.

С такими вопросами тебе рановато "компиляторописательством" заниматься ИМХО.

Добавлено через 9 минут и 43 секунды
http://board.flatassembler.net/topic.php?t=3437

Автор: bems 3.9.2013, 10:28
Цитата(ТарасАтавин @  3.9.2013,  09:49 Найти цитируемый пост)
Каким образом возвращается значение при завершении приложения?
передаётся параметром в ExitProcess, которую должен вызвать рантайм (не компилятор)

Цитата(ТарасАтавин @  3.9.2013,  09:49 Найти цитируемый пост)
Как указать точку входа на ассемблере и в коде исполняемого файла?
в экзешнике - поле AddressOfEntryPoint опционального заголовка РЕ

Цитата(ТарасАтавин @  3.9.2013,  09:49 Найти цитируемый пост)
Как на низком уровне организован консольный ввод/вывод?
с точки зрения прикладного процесса - вызовами API ReadFile/WriteFile

Цитата(ТарасАтавин @  3.9.2013,  09:49 Найти цитируемый пост)
Надо ли специально регистрировать экспортируемые функции в GetProcAdress? И как? 
создать секцию экспорта, в соответствии с описанием формата РЕ



Автор: ТарасАтавин 4.9.2013, 08:09
Цитата(_zorn_ @  3.9.2013,  10:08 Найти цитируемый пост)
Начнем с того что это не так. main - это библиотечная функция
Бред. Автор консольной проги функцию main пишет сам.

Автор: _zorn_ 4.9.2013, 08:18
Цитата(ТарасАтавин @ 4.9.2013,  16:09)
Бред. Автор консольной проги функцию main пишет сам.

Бред. Автор консольной проги НА АСМЕ может назначить точку входа куда угодно, даже не на функцию.
И почитайте про PE формат хотя бы.

Автор: ТарасАтавин 4.9.2013, 08:25
Цитата(_zorn_ @  3.9.2013,  10:08 Найти цитируемый пост)
которая вызывается после всяких инициализаций.
Возможно это так на низком уровне c++-программы. Но если нет глобальных объектов, то первая явная (прописанная на высоком уровне) операция находится в main, отсюда иное понимание точки входа у крестанутых. Хорошо, пусть на самом деле это не так. А что отвечает за инициализации? Система? Или ещё одна подпрограмма приложения? В первом случае точка входа всё таки в main и к разрабатываемому компилятору это относится вне зависимости от наличия глобальных объектов, так как вызов глобальных конструкторов он, в отличие от компиляторов c++, должен неявно добавить в main. А во втором случае на что она вообще похожа?

Добавлено через 3 минуты и 10 секунд
Цитата(bems @  3.9.2013,  10:28 Найти цитируемый пост)
передаётся параметром в ExitProcess
А на уровне операций это как выглядит? 
Цитата(bems @  3.9.2013,  10:28 Найти цитируемый пост)
которую должен вызвать рантайм (не компилятор)
 Специфично ли это именно для c/c++? А на паскале как возвращается значение?

Автор: _zorn_ 4.9.2013, 08:30
В прошлый раз не правильно выразился. main - функция вызываемая ИЗ библиотечных функций инициализации. Которые в свою очередь и подготавливают параметры для main.

Автор: ТарасАтавин 4.9.2013, 08:32
Цитата(bems @  3.9.2013,  10:28 Найти цитируемый пост)
с точки зрения прикладного процесса - вызовами API ReadFile/WriteFile
А при чем здесь файлы? Клавиатурный ввод с командной строки и вывод на экран. Потоки std::cin и std::cout, а не std::ifstream s1 и std::ofstream s2. Или имеется ввиду фиктивный файл CON, или как его там ещё?

Добавлено через 1 минуту и 46 секунд
Цитата(_zorn_ @  4.9.2013,  08:18 Найти цитируемый пост)
Бред. Автор консольной проги НА АСМЕ может назначить точку входа куда угодно, даже не на функцию.
И почитайте про PE формат хотя бы. 
Речь о компилируемых программах и правилах языка высокого уровня.

Автор: _zorn_ 4.9.2013, 08:35
Цитата(ТарасАтавин @  4.9.2013,  16:25 Найти цитируемый пост)
А что отвечает за инициализации? Система? Или ещё одна подпрограмма приложения?

Компилятор. Вернее скорее линкер - это типа стаба. 
На что это похоже можешь посмотреть в той же IDA перейдя на entrypoint

Цитата(ТарасАтавин @  4.9.2013,  16:25 Найти цитируемый пост)
А на уровне операций это как выглядит? 

Код

push 0
call ExitProccess

Автор: ТарасАтавин 4.9.2013, 08:37
Цитата(_zorn_ @  3.9.2013,  10:08 Найти цитируемый пост)
Консольный ввод/вывод так же выполняется библиотечными функциями обертками, которые в свою очередь могут использовать WinAPi.
Библиотечные функции для перегруженных операторов, о которых в языке явно сказано, что они инлайнятся? Однако. Ни каких библиотек, вызовы API требуется встроить по месту. Какие?

Добавлено через 46 секунд
Цитата(bems @  3.9.2013,  10:28 Найти цитируемый пост)
в экзешнике - поле AddressOfEntryPoint опционального заголовка РЕ
А где бы почитать описание формата заголовка PE?

Добавлено через 1 минуту и 54 секунды
Цитата(_zorn_ @  4.9.2013,  08:35 Найти цитируемый пост)
 IDA перейдя на entrypoint
Что это?

Автор: _zorn_ 4.9.2013, 08:40
Цитата(ТарасАтавин @  4.9.2013,  16:32 Найти цитируемый пост)
Потоки std::cin и std::cout, а не std::ifstream s1 и std::ofstream s2.

Всякие библиотечные функи/рантаймы/пёс с горы. На что фантазии хватит у разработчика языка/компилятора
В твоем примере это STL

Автор: ТарасАтавин 4.9.2013, 08:41
И регистры по сегментам надо раскладывать?

Автор: _zorn_ 4.9.2013, 08:51
Цитата(ТарасАтавин @  4.9.2013,  16:41 Найти цитируемый пост)
И регистры по сегментам надо раскладывать? 

Что что ?

Начни с простого
http://ru.wikipedia.org/wiki/Portable_Executable

IDA - https://www.hex-rays.com/products/ida/support/download_demo.shtml
Понадобится для х64 (полная), сам найдёш.

Автор: ТарасАтавин 4.9.2013, 08:52
Цитата(_zorn_ @  4.9.2013,  08:40 Найти цитируемый пост)
Всякие библиотечные функи/рантаймы/пёс с горы. На что фантазии хватит у разработчика языка/компилятора В твоем примере это STL
Разрабатываемый компилятор не может, встретив перегруженный оператор, в том числе оператор потокового вывода, или потокового ввода, поставить вызов библиотечной функции, а должен встроить копию её тела по месту, вызов же должен быть сразу в API. Это требование, можете считать, что стандарта. К тому же её ещё надо написать. Какой именно нужен вызов API? Дан адрес нуль-терминальной строки в кодировке ANSI, требуется вывести её на экран. Что следует вызвать? Как зовут функцию? Где мне взять её адрес и как вызвать? Какие у неё параметры? Как они передаются? Через стек? Или через регистры? Какой параметр через какой регистр передаётся? Какова семантика каждого параметра?

Автор: _zorn_ 4.9.2013, 08:58
Батенька, да вам пока еще из msdn рано вылазить.
А так на вскидку первое что пришло в голову.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687401%28v=vs.85%29.aspx

Добавлено через 9 минут и 26 секунд
Для вызова функции есть секция импорта (читай про PE формат, БЛДЖАД)
А на остальные вопросы, есть такое страшное словосочетание - http://ru.wikipedia.org/wiki/%D1%EE%E3%EB%E0%F8%E5%ED%E8%E5_%E2%FB%E7%EE%E2%E0  smile 

Автор: bems 4.9.2013, 10:35
Цитата(ТарасАтавин @  4.9.2013,  08:25 Найти цитируемый пост)
А на уровне операций это как выглядит? 
как на уровне oпераций выглядит передача параметра в функцию зависит от конвенции вызова. на х64 используется регистр, место в стеке всё равно резервируется (с выравниванием) и делается call

Цитата(ТарасАтавин @  4.9.2013,  08:25 Найти цитируемый пост)
Специфично ли это именно для c/c++? А на паскале как возвращается значение? 

и на паскале ExitProcess
потому что win api един

Цитата(ТарасАтавин @  4.9.2013,  08:32 Найти цитируемый пост)
А при чем здесь файлы? Клавиатурный ввод с командной строки и вывод на экран. Потоки std::cin и std::cout, а не std::ifstream s1 и std::ofstream s2. Или имеется ввиду фиктивный файл CON, или как его там ещё?
стандартный вводной поток в винде это тоже "файл". он может совпадать с CON а может и не совпадать

Цитата(ТарасАтавин @  4.9.2013,  08:37 Найти цитируемый пост)
А где бы почитать описание формата заголовка PE?
http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx


ты бы для начала написал компилятор какого-нить простого языка, хоть бы бейсика, для опыта. а то с плюсами ты завязнешь на 15 лет, и так ничего и не сделаешь

Автор: LeonidPr 5.9.2013, 12:43
Разложу ваши вопросы, которые вы задали в первом посте в куче по пунктам и попробую ответить
Цитата(ТарасАтавин @  3.9.2013,  09:49 Найти цитируемый пост)

1. С чего начинать создание приложения на ASM и в опкоде и изучение вопроса?
2. Надо ли вообще раскладывать регистры по сегментам и как?
3. Как это выглядит в коде исполняемого файла?
4. Каким образом возвращается значение при завершении приложения?
5. Как получить доступ к параметрам функции main (содержащей точку входа)?
6. Как указать точку входа на ассемблере и в коде исполняемого файла?
7. Как организован стек в Windows-приложении x64?
8. Как на низком уровне организован консольный ввод/вывод? 
9. Надо ли специально регистрировать экспортируемые функции в GetProcAdress? И как?

1. Начинать с написания кода на языке ассемблер как ни странно. В опкодах писать не советую- ибо тяжко (на то компиляторы/ассемблеры и нужны). Изучение начинать с курса по компиляторам (на Intuit вроде есть), книг по компиляторам, этапов компиляции (Лексический анализ, синтаксический анализ, кодогенерация+оптимизация) книга Дракона вам в руки + статьи по этому делу
2. Регистры по сегментам??? вы о чем? адресное пространство вроде как плоское...
3. Читайте доки по формату PE, там все разжевано (книжка есть http://www.ozon.ru/context/detail/id/1696616/
4.  Отвечали уже - в параметре ExitProcess
5. В стеке лежат
6. В ассемблере end <точка входа> в конце .asm файла, в коде - см п.3
7. для Win 64 не программировал, но думаю, что вряд ли сильно отличается от Win32 - ESP и push/pop
8. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682073%28v=vs.85%29.aspx
9.Нет. Если вы создаете DLL там есть секция экспорта

Автор: bems 5.9.2013, 15:18
Цитата(LeonidPr @  5.9.2013,  12:43 Найти цитируемый пост)
7. для Win 64 не программировал, но думаю, что вряд ли сильно отличается от Win32 - ESP и push/pop

ну там нет "цепочки ebp"

Цитата(LeonidPr @  5.9.2013,  12:43 Найти цитируемый пост)
8. MSDN
ввод-вывод может быть перенаправлен, нельзя предполагать что стандартный вывод это всегда консоль



Автор: LeonidPr 5.9.2013, 15:51
Цитата(bems @  5.9.2013,  15:18 Найти цитируемый пост)
ну там нет "цепочки ebp"

Буду знать, спасибо.
Цитата(bems @  5.9.2013,  15:18 Найти цитируемый пост)
ввод-вывод может быть перенаправлен, нельзя предполагать что стандартный вывод это всегда консоль

Согласен. Просто вопрос был именно про консоль.

Автор: ТарасАтавин 7.9.2013, 13:38
Цитата(_zorn_ @  4.9.2013,  08:51 Найти цитируемый пост)
Что что ?
Ну как в досе: сегмент, зовут его так то, регистр у него такой то.

Добавлено через 5 минут и 44 секунды
Цитата(_zorn_ @  4.9.2013,  08:58 Найти цитируемый пост)
А на остальные вопросы, есть такое страшное словосочетание - конвенция вызовов
Ещё бы знать соглашение о вызовах для нужной функции. Их ведь много разных.

Автор: bems 7.9.2013, 13:44
В винде плоское адресное пространство.
Исполняемый файл организован не в сегменты а в секции, адреса которых не должны быть в регистрах. Сегментные регистры используются, но подругому

Автор: ТарасАтавин 7.9.2013, 13:44
Цитата(_zorn_ @  4.9.2013,  08:35 Найти цитируемый пост)
код Ассемблера
1:
2:
push 0
call ExitProccess
Она системная?

Автор: bems 7.9.2013, 13:46
да http://msdn.microsoft.com/en-us/library/windows/desktop/ms682658%28v=vs.85%29.aspx
и push на х32, а на х64 другая конвенция вызова http://blogs.msdn.com/b/oldnewthing/archive/2004/01/14/58579.aspx

Автор: ТарасАтавин 7.9.2013, 13:47
Цитата(bems @  4.9.2013,  10:35 Найти цитируемый пост)
ты бы для начала написал компилятор какого-нить простого языка, хоть бы бейсика, для опыта
Ты уж определись: или простого, ли не спроста интерпретируемого бейсика.

Автор: bems 7.9.2013, 13:48
Цитата(ТарасАтавин @  7.9.2013,  13:38 Найти цитируемый пост)
Ещё бы знать соглашение о вызовах для нужной функции. Их ведь много разных.
на х64 только одна

Автор: ТарасАтавин 7.9.2013, 13:48
Цитата(bems @  4.9.2013,  10:35 Найти цитируемый пост)
 а то с плюсами ты завязнешь на 15 лет, и так ничего и не сделаешь
Я вообще не собираюсь писать ещё один компилятор плюсов.

Автор: bems 7.9.2013, 13:49
Цитата(ТарасАтавин @  7.9.2013,  13:47 Найти цитируемый пост)
Ты уж определись: или простого: ли не спроста интерпретируемого бейсика.
есть и компиляторы бейсика. и есть среди них даже такие, которые не представляют из себя замаскированный интерпретатор smile
ну напиши Паскаля

Добавлено через 16 секунд
Цитата(ТарасАтавин @  7.9.2013,  13:48 Найти цитируемый пост)
Я вообще не собираюсь писать ещё один компилятор плюсов.
окей

Автор: ТарасАтавин 7.9.2013, 13:53
Цитата(bems @  7.9.2013,  13:49 Найти цитируемый пост)
есть и компиляторы бейсика. 
я одним даже компилил. Но почему то в отличие от паскаля/C/C++ для него всё таки исконно преобладали интерпретаторы. Не потому ли, что сложно компилить язык, с объявлением переменной при первом присваивании, чудным присваиванием через LET, с зависимостью типа переменной от её имени и тому подобными дебрями?

Добавлено @ 13:54
Цитата(bems @  7.9.2013,  13:49 Найти цитируемый пост)
ну напиши Паскаля
Я на Вирата похож?

Добавлено через 3 минуты
Цитата(bems @  7.9.2013,  13:44 Найти цитируемый пост)
 Сегментные регистры используются, но подругому 
Как? И надо ли их куда то назначать и что то в них загружать?

Автор: bems 7.9.2013, 14:00
Цитата(ТарасАтавин @  7.9.2013,  13:53 Найти цитируемый пост)
чудным присваиванием через LET
это не влияет на то как это компилировать, просто особенности синтаксиса

Цитата(ТарасАтавин @  7.9.2013,  13:53 Найти цитируемый пост)
с зависимостью типа переменной от её имени и тому подобными дебрями?
не дебри, и это тоже не трудно обработать

Цитата(ТарасАтавин @  7.9.2013,  13:53 Найти цитируемый пост)
Я на Вирата похож?
на самом деле ты похож на излишне деятельного подростка. вопросы которые ты задаешь ясно показывают что гонору у тебя больше чем знаний.

Добавлено через 6 минут и 40 секунд
Цитата(ТарасАтавин @  7.9.2013,  13:53 Найти цитируемый пост)
Как?
например в х32 регистр FS указывает на TIB, соответственно используется при установке SEH-фреймов, работе с tls и тд

Автор: ТарасАтавин 7.9.2013, 14:34
Цитата(bems @  7.9.2013,  14:00 Найти цитируемый пост)
на самом деле ты похож на излишне деятельного подростка. вопросы которые ты задаешь ясно показывают что гонору у тебя больше чем знаний.
У кандидата наук мало знаний? Гонора же не хватило даже на то, чтоб подавать на доцента.

Автор: bems 7.9.2013, 14:45
Цитата(ТарасАтавин @  7.9.2013,  14:34 Найти цитируемый пост)
У кандидата наук мало знаний?

профильных - да

Цитата(ТарасАтавин @  7.9.2013,  14:34 Найти цитируемый пост)
Гонора же не хватило даже на то, чтоб подавать на доцента.
вот что на предложение про гонор ты ответишь у меня сомнений небыло. ты бы так рьяно отвечал в тематическом диалоге. 
например о том что stdout != консоль. или вот в этой теме http://forum.vingrad.ru/forum/topic-371647.html

Автор: ТарасАтавин 7.9.2013, 14:47
Цитата(bems @  7.9.2013,  14:45 Найти цитируемый пост)
профильных - да
А ничего, что по теме я сам назвался новичком? Но у меня достаточно знаний, чтоб самостоятельно сочинить хотябы задачу, в том числе, по теме. А способность разобраться, чтоб сделать хоть что то, у к.т.н. вряд ли может отсутствовать. Вот во времени может быть вопрос. Но я где то называл сроки?

Автор: bems 7.9.2013, 14:48
Тарас, это снова ответ не на профильную реплику smile
ЧТД

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)