связка Visual C++ 2017 с MASM

Тема в разделе "WASM.BEGINNERS", создана пользователем kol1978, 18 фев 2025.

  1. kol1978

    kol1978 Member

    Публикаций:
    0
    Регистрация:
    16 фев 2025
    Сообщения:
    35
    ", а не ядро линукс и тем более не какое окружение там настроено..." - мною было где то сказано относительно генерации чего ли бо ядром linux? где мной сказано про ядро linux...??? и поэтому бредишь похоже ты сам...
    --- Сообщение объединено, 23 фев 2025 в 11:43 ---
    Первое - нужно мне... цель - разобраться в изложении материала книги.
    Второе - ответ услышан... ты не пуп земли...
    Третье - добиться доказательство ответа: это точно ELF? и в заключении ответ на вопрос по теме поста - связка Си и ассемблера.
     
  2. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    149
    Не зависит. Только от версии gcc и библиотек в системе, используемых твоей программой. Соответственно библиотекам ставятся и заголовки к ним, которые могут содержать инструкции gcc для генерации той или иной конструкции в конечном файле. После создания .s файла вы получаете уже готовый к производству бинарного файла набор инструкций и директив ассемблера, который подключается к вашему проекту как он есть без изменения (только те флаги, на которые реагирует ассемблер).

    Вообще процесс компиляции можно разбить на два этапа, которые gcc выполняет подряд или останавливается после превого.
    Когда вы даете gcc файл .c или .cpp или .s (или любой другой исходник), тогда вы заставляете gcc перенаправить команду в компилятор. Компилятор создает из этого исходника бинарный файл для линкера .o или .obj. Но если вы говорите создать .s файл, тогда на выходе получаете .s файл исходника и уже линке его прожевать не сможет (процесс останавливается после первого этапа). После сборки всех исходных текстов в объектный (бинарный) формат запускается линкер, который оперирует блоками данных из этих объектных файлов. Он собирает весь код в одну секцию, все данные в одну секцию, а так же приправляет все это исправлениями для доступа из одного блока кода к его блоку переменных, а не в рандомное место. Вот на этом процессе и возникают проблемы с адресацией дальше 2 Гб, когда в коде уже заложена арифметика указателей не оперирующая смещениями больше 32 бит. Линкеру надо подставить в код новое смещение, а оно требует для размещения не 32-х, а большего числа бит (64-х).

    Вот и вся ваша проблема. А в чем проблема у вас с совмещением тоже не понятно. К тому же в теме вы пишите про MASM, но так и не использовали его (все больше используете as - gnu assembler).

    Еще для обсуждения ваших вопросов не плохо было бы показать версии вашего компилятора, чтобы спрашивать о коде, который он создает для своих нужд.
    --- Сообщение объединено, 23 фев 2025 в 12:11 ---
    Т.е. о MSYS2 или MinGW вы не слышали.
    --- Сообщение объединено, 23 фев 2025 в 12:12 ---
    И про WSL тоже не слышали
    --- Сообщение объединено, 23 фев 2025 в 12:12 ---
    Не знаете - записали.
    --- Сообщение объединено, 23 фев 2025 в 12:15 ---
    Для ответа на эти вопросы вам надо искать все в исходниках к соответствующим версиям компиляторов. Т.к. вы спрашиваете о служебном коде, который генерирует конкретная версия для работоспособности программы.
     
  3. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    516
    Если ты увидел эту ошибку, то всё, ты дальше долбишься в закрытую дверь - у тебя компилятор не может делать ELF с сегментами более 2Гб несмотря на 64-битность.
    Эта дверь закрыта, переходи к следующему вопросу из книги, тем более что это явно вопрос не из книги.

    На винде безусловный отлуп - сами 64-битные PE+ просто забиты 32-битными полями и тупо не могут быть больше 2Гб.
    Нужна Windows 15+ чтобы ситуация изменилась.

    На линуксе интереснее - судя по гуглу там таки есть REL64_64, т.е. 64-битные релокации, но компилятор должен быть собран с поддержкой этого добра и более того - libc с crt тоже должны быть собраны в режиме -mcmodel=large, что уже другая даже плоскость вопроса, но тоже необходимая. И судя по всему по дефолту из-за тех накладных расходов что large model накладывает этим никто не хочет заморачиваться даже. Поэтому задачка нетривиальная.
    Дойдут руки посмотрю как в моей бубунте дела обстоят.
     
  4. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    149
    На это ответили еще на 4 странице - ограничение формата исполняемого файла, но оно связано с ограничениями в инструкциях процессора.
    --- Сообщение объединено, 23 фев 2025 в 12:18 ---
    Если книга подает материал так не качественно, тогда стоит взять книгу по проще, а после вернуться к изучению этой. Иначе у вас и так каша в голове совсем убежит.
     
  5. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    516
    Исправляюсь - проблема в линуксе не в этом, тут у меня самого в голове смешалось то, что происходит в Windows. В линуксе же пока что единственное что я вижу по гуглу сам не попробовав - это то, что используются несмотря на -mcmodel=large 32-битные релокации (REL64_32) в таблицах релокации и поэтому линковщик пасует. Но это пока еще не значит что проблема в размерах сегментов. Более того - проблема возможно вообще только в том, что crt и libc скомилированы без опции -mcmodel=large и поэтому именно линковка с ними вызывает ошибку, а если бы мы писали чисто собственный код да еще на асме, то проблемы бы тоже не было. Дойдут руки попробую проверить.
     
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.912
    MaKsIm, aa_dav,
    топикстартер одну неделю не сможет отвечать на ваши вопросы, dura lex, sed lex...
     
    TermoSINteZ нравится это.
  7. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    149
    С этим головняком позволят развлечься Gentoo или Arch. Нужен -mcmodel=large у libc - просто собери сам.
     
  8. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    516
    Кстати да, версия, что в линуксе подвох только в том, что libc скомпилирован без -mcmodel=large получает всё больше подтверждений в обсуждении на других ресурсах.
    Опыт простейший надо сделать, скомпилировать следующую программу с двумя вариантами ключей:
    Код (Text):
    1.  
    2. #include <iostream>
    3. #include <cstring>
    4.  
    5. const long long strSize = 1500000000; // 1.5 Гб
    6. char message1[strSize]; // этот массивчик пойдёт в секцию data PE
    7. const char message2[strSize] = { 1 }; // а этот в секцию rdata
    8.  
    9. int main(int argc, char *argv[])
    10. {
    11.   memset(message1, 1, strSize);
    12.   message1[strSize - 1] = 0;
    13.   std::cout << strlen(message1) << " " << message2 << "\n";
    14.   return 0;
    15. }
    16.  
    С -mcmodel=small она обязана не скомпилироваться.

    А вот далее компилировать надо с -mcmodel=medium и -mcmodel=large.

    Скорее всего на любой системе первое скомпилируется - потому что -mcmodel погружает сегменты с кодом и маленькие данные в первые первые 2Гб и даже если libc скомпилирован в small он просто должен туда попасть и не будет порождать ошибок.
    А вот если второе при этом не скомпилируется, то это просто подтвердит эту же версию.
    Но сам пока никак не могу добраться до линукса, хотя уже почти уверен что так дела и обстоят.
     
  9. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    613
    aa_dav, не очень понимаю нахрена городить статики столько, кода на 2 ГБ это как вообще. Память вызываем динамически...
    Попытался твой код скомпилировать на UASM64, быстро его перевёл, на малых данных компилируется, но с 1'500'000'000, сначала на долго задумывается, а потом сообщает о ошибке памяти.
    Код (ASM):
    1. .x64
    2. option casemap:none
    3. option frame:auto
    4. option LITERALS:ON
    5. IF @Platform EQ 1
    6.   APP_WIN64 EQU 1
    7. ENDIF
    8. include windows.inc
    9. include msvcrt.inc
    10. includelib msvcrt.lib
    11. include \assemblers\include\macros.asm
    12. strSize    = 1500000000 ;// 1.5 Гб
    13. .data
    14. message1 byte strSize dup (?) ;// этот массивчик пойдёт в секцию data PE
    15. .const
    16. message2 byte strSize dup (1) ;// а этот в секцию rdata
    17. .code
    18. main proc frame argc:sdword, argv:ptr ptr, envp:ptr ptr
    19. ;argc:ecx, argv:rdx, envp:r8
    20.   memset(&message1, 1, strSize)
    21.   mov message1[strSize - 1], 0
    22.   printf$("%lld %s\n", strlen(&message1), &message2)
    23.   xor eax, eax
    24.   ret
    25. main endp
    26. main_startup3_END
    UASM рулит, но тут вероятно тоже надо какие-то опции включать.
    Ватник.
    Код ( (Unknown Language)):
    1. @echo off
    2. set _name_="test4gb"
    3. set _path_="\assemblers"
    4. %_path_%\bin\uasm64 -win64 /c /I%_path_%\include\x64 %_name_%.asm
    5. %_path_%\bin\link /SUBSYSTEM:CONSOLE /machine:x64 /LARGEADDRESSAWARE:NO /LIBPATH:%_path_%\lib\x64 %_name_%.obj
    6. if exist %_name_%.obj del %_name_%.obj
    7. pause
    --- Сообщение объединено, 26 фев 2025 в 11:40 ---
    Апд:
    Ассемблер скомпилировал код, работал 303 сек. А вот линкер подавился, ошибка LNK1248. Надо линкер 64 битный...
    --- Сообщение объединено, 26 фев 2025 в 11:56 ---
    Не, получается РЕ не поддерживает такие файлы, а линукса у меня нет, и использовать его не планирую.
     
  10. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    516
    Да это просто проверка способен ли компилятор и ОСь на 64-bit ultra super force unleashed или есть какие то затыки, т.к. создатели думают, что не время еще всю собаку с цепи спустить.
    Ну да, в винде получается даже формат выполнимого файла еще тянет ограничения 32-бит.
    А в линуксе вроде как сделали, но так, что надо еще немного (или много) постараться.
     
  11. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    149
    Код (Bash):
    1.  
    2. xchgeaxeax@home-kde ~/testDir/2gbTest $ cat ./main.cpp
    3. #include <iostream>
    4. #include <cstring>
    5. const long long strSize = 1500000000; // 1.5 Гб
    6. const char message1[strSize] = { 0 }; // этот массивчик пойдёт в секцию rdata
    7. const char message2[strSize] = { '1' }; // а этот в секцию rdata
    8. int main(int argc, char *argv[])
    9. {
    10.   std::cout << strlen(message1) << " " << message2 << "\n";
    11.   return 0;
    12. }
    13. xchgeaxeax@home-kde ~/testDir/2gbTest $ g++ -mcmodel=small -o ./2gbtest_small ./main.cpp
    14. [B]многа нецензурной лексики в мой адрес[/B]
    15. collect2: ошибка: выполнение ld завершилось с кодом возврата 1
    16. xchgeaxeax@home-kde ~/testDir/2gbTest $ g++ -mcmodel=medium -o ./2gbtest_medium ./main.cpp
    17. xchgeaxeax@home-kde ~/testDir/2gbTest $ g++ -mcmodel=large -o ./2gbtest_large ./main.cpp
    18. xchgeaxeax@home-kde ~/testDir/2gbTest $ ./2gbtest_medium
    19. 0 1
    20. xchgeaxeax@home-kde ~/testDir/2gbTest $ ./2gbtest_large
    21. 0 1
    22. xchgeaxeax@home-kde ~/testDir/2gbTest $ ls -la
    23. итого 5859412
    24. drwxr-xr-x 1 xchgeaxeax xchgeaxeax         70 фев 26 15:52 .
    25. drwxr-xr-x 1 xchgeaxeax xchgeaxeax       3340 фев 26 15:40 ..
    26. -rwxr-xr-x 1 xchgeaxeax xchgeaxeax 3000016112 фев 26 15:52 2gbtest_large
    27. -rwxr-xr-x 1 xchgeaxeax xchgeaxeax 3000016376 фев 26 15:52 2gbtest_medium
    28. -rw-r--r-- 1 xchgeaxeax xchgeaxeax        381 фев 26 15:51 main.cpp
    29.  
    Я не стал городить огородов и сделал так. Получились эльфы по 3 Гб каждый и даже нормально выполнились. А вот -mcmodel=small как раз из-за размеров и не смогла собраться. Линкер сказал, что так нельзя.