| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Asm: Общие вопросы > Помогите с линковкой |
| Автор: Гость_Andrey 4.6.2004, 18:39 |
| Помогите кто может. Скачал и установил MASM 6.13. Вроде бы все круто, написал мин. приложение, откомпилировал: ml.exe /c /coff first.asm Пытаюсь линковать: link.exe firs.obj /subsystem:windows а он говорит что неизвестный параметр /subsystem |
| Автор: Гость_Andrey 4.6.2004, 18:55 |
| Это не оригинальный линковщик. (Не тот который ставился с MASM), а скаченый с какогото сайта. Оригинальный линковщик вообще ничего не выдает и ничего не делает. Можно написать для него любую строку, любую абракадабру, а он проглотит и даже ничегоне напишет. |
| Автор: Chingachguk 5.6.2004, 10:17 |
| Батник: [code] @echo off if exist %1.obj del %1.obj if exist %1.exe del %1.exe \masm32\bin\ml /c /coff %1.asm if errorlevel 1 goto errasm if not exist rsrc.obj goto nores \masm32\bin\Link /SUBSYSTEM:WINDOWS %1.obj rsrc.obj if errorlevel 1 goto errlink dir %1.* goto TheEnd :nores \masm32\bin\Link /SUBSYSTEM:WINDOWS %1.obj if errorlevel 1 goto errlink dir %1.* goto TheEnd :errlink echo _ echo Link error goto TheEnd :errasm echo _ echo Assembly Error goto TheEnd :TheEnd pause [quote] |
| Автор: Гость_Andrey 6.6.2004, 15:46 |
| Thaks. Правда приведенный батник не понадобился. Я просто скачал и установил дополнение MASM - 2005 по ссылке http://www.wasm.ru/tools/7/BIN.2005.zip. По мимо всякой прочей лабуды там оказался ликовщик, который не ругается на параметр /SUBSYSTEM:WINDOWS. Еще один вопрос возник: Сегментные регистры FS,GS и т.д. можно ли использовать как временные переменные (под Windows). Или лучше этого не делать. Другое применение в небольших программах для них придумать сложно. |
| Автор: Chingachguk 6.6.2004, 16:35 | ||
Что значит - делать или не делать ? Что делать ? Вообще-то они предназначены для хранения сегментов (селекторов). Однако win32-приложения не используют оперирование сегментами (архитектура такая) - не то, что в DOS. Если, к примеру, в дос было понятие 64-килобайтного сегмента и программа получала при запросе памяти ее адрес в виде комбинации сегмент:смещение, то в win при аналогичном запросе она получает лишь 32-х битный offset. Это не означает, что ОСЬ отдает все адресное пр-во во владение программам в виде большого массива: контроль ведется на уровне страниц. Однако при попытке программировать системные вещи уже начинаешь использовать селектора. Например, такая вещь, как SEH - обработчик исключений для user-кода. Например, при таком обрамлении на Дельфи: try ... exception: ... finally: Компиллятор воткнет в прологе установку собственного обработчика ошибок, и в finally восстановит прежний обработчик. Все структуры для установки SEH лежат в FS:[0...], те селектор этот используется. Или при вызове GetTickCount система (я про win98) вытащит инкрементальный счетчик из ~ GS:[0]. SEH часто используют защиты уровня приложения для самораспаковки, что немного затрудняет их анализ ;) Даже при программировании драйверов нечасто используешь манипуляции с селекторами. Однако иногда их свойства могут быть полезны... |
| Автор: Гость_Andrey 8.6.2004, 09:48 |
| Ну драйвера я пока не программирую. Пока я занимаюсь более приземленными вещами. А имел ввиду я следующее. Например, в нектором месте программы мне нужно сохранить некторый регистр, что бы потом его использовать. Конечно я могу сделать push xx ...... pop xx Все отлично. Но - этот участок кода находиться в очень большом цикле, да еще в двойном (цикл вложенный в цикл). Так как с регистрами работа происходит гораздо быстрее, то нельзя ли мне не в стек запихивать свою переменную, а, например, в fs? Я конечно понимаю, что даже если я этого добьюсь, то наврядли замечу существенного ускорения, но все же хочется усовершенствовать по максимому. Я пробовал, вроде работает. Правда не всегда. Возможно это из-за того, что не разрешается различные страницы использовать. Может он воспринимает это как селектор страницы и получается исключение по доступу к неправильному участку памяти (ну в смысле не к своему). В общем не знаю, поэтому и решил спросить, может что скажете по этому поводу. |
| Автор: _Chingachguk_ 8.6.2004, 10:18 | ||
Совершенно верно ! Немного не так, другое исключение - но в целом верно, в сегментный регистр нельзя писать произвольные числа. Это можно проверить циклическим присвоением. Насчет быстродействия. Это не лучший способ по многим причинам. Хотя бы по тем, что при команде mov eax,ebx ; Сохранить ebx в eax процессор НЕ выполняет проверок на корректность значения, а вот при команде: mov fs,ax очевидно, выполняет проверки на корректность селектора, и очень вероятно, тратит больше времени. Точнее - см. таблицу времени выполнения команд. К тому же в 32-х битном коде многие значения не помещаются в 16-ть бит селектора. Команды же со стеком сейчас, на современных процессорах, работают очень быстро (1-2 такта). Гораздо больший вклад в быстодействие вносит конвеер - спариваемость команд. Кратко принцип такой: если вторая из двух команд требует результата выполнения первой, то процессор не может выполнить эти команды параллельно и быстродействие снижается. Например, P3 800 может работать на некоторых алгоритмах НЕ МЕДЛЕННЕЕ P4 1600 ! Пример неспаренных команд: mov eax,[ebx] ; use eax mov ecx,[ebx+eax] ; use eax - AGI ! В целом быстродействие отлаживается вручную и неплохо овладеть общими приемами вроде вышеприведенного и навыками измерения времени выполнения отдельно взятых кусков программы. |
| Автор: Гость_Andrey 30.6.2004, 18:08 |
| Возникли еще глупые вопросы (куда же без них 1. Можно ли с помощью LOCAL делать локальные массивы (в стеке в смысле). Если да, то каким образом. Сколько не пробовал, ничего не получается. 2. Каким образом можно сделать динамический массив. Т. е. вопрос в том, как работать с динамической памятью (массивы не в стеке, а именно в динамической памяти). Просто появилась задача - есть набор строк, а их число до момента выполнения программы неизвестно. Причем работать с этими строками будут разные функции на протяжении работы всей программы. Так что стек для хранения здесь как то не подходит. |
| Автор: oleg1973 1.7.2004, 09:16 | ||||
proc SomeShit enter тут код и все такое return вот и будет массив в стеке для некой процедуры Someshit
выделив заранее бОльший кусок памяти чем может понадобится p.s. я вот только господа асемблершики не пойму почему так все любят пихать данные в стек? (имеются ввиду массивы всякие) этоже не совсем удобно. поясню свою точку зрения 1) если массив с известным размером, можно просто сделать алокейш памяти ,на esi к примеру поинтер и работай себе спокойно 2) если массив с неизвестным размером (нууу очень редко бывает при програмировании на асме), поступаем аналогично выделив кусок памяти и меняя его размер по необходимости преимушества на мой взгляд очевидны если в системе ну нету больше памяти то она и не выделится и прога ваша спокойно завершится, а вот размер стека и размер ваших данный система контролировать не может, так что можно получить и переполнение |
| Автор: Guest 3.7.2004, 11:39 |
| Thank you!!! Я так и сделал. Выделил нужный кусок памяти и все стало нормально. А со стеком (массивы в стеке хранить), это действительно не очень хорошо. Просто это очень легко и удобно (уменьшил esp и все в порядке). Для небольших массивов (имя с клавы спросить, или еще чего), очень удобно. |
| Автор: oleg1973 3.7.2004, 12:28 |
| ну дык для мелких массивов делай секцию неинициализированных данных она место в фале не занимает, а ОС при загрузке сама выделит память для массива, таким образом избежиш гемороя с GlobalAlloc и прочим |
| Автор: MORRA 2.11.2004, 05:51 |
| О хранении промежуточных данных в сегментых регистрах: Теоретически можно, но на практике лучше воспользоваться стеком или переменными в памяти, например, так: main: ;если изначально переменная размером с байт в регистре AL mov var, al ... mov al, var end main var db 0 и зачем, спрашивается, изобретать велосипед? А все дело в том, что сегментные регистры имеют так называемую теневую часть размером с двойное слово, которая, фактически, недоступна, но представляет собой некоторое подобие дескриптора сегмента, а их этого следует, что любое значение в сегментном регистре просто так "не сходит с рук" |