• Как перевести этот код с C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как перевести этот код с C++?

    И, главное, зачем? И чем для этой цели не подошёл компилятор С++?

    mov ebx, [ebp - 8]

    Нифига не mov, должно быть lea ebx, [ebp - 8]

    lea edx, [ebx + ecx + 4] ; add FirstThunk RVA to base. Offset &function is 4

    Нифига +4 не нужно. Смещение &function == 0.

    lea edx, [edx + 20] ;size of IMAGE_THUNK_DATA

    Нифига не +20, размер этой структуры -- 4.
    Ответ написан
    3 комментария
  • Что можно улучшить в этой функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    можно ли ее как-то улучшить

    Зависит от того, что считать улучшением.
    По размеру кода -- вряд ли можно улучшить существенно.
    По скорости -- можно, если загружать данные из памяти выравненными словами и раскрутить цикл.
    По простоте -- можно существенно улучшить, переписав её на С или вообще воспользовавшись готовой реализацией.
    Ответ написан
    1 комментарий
  • Почему в windows адреса называются "виртуальными"?

    Radjah
    @Radjah
    Потому что система работает в защищённом режиме процессора, в котором напрямую с памятью работает только ядро.
    Каждому процессу ядро выделяет адресное пространство, которое проецируется на реальные адреса оперативной памяти.

    Короче вот https://ru.wikipedia.org/wiki/Защищённый_режим

    Если хочешь гонять байтики без подобный преобразований, то тебе в DOS, там реальный режим.
    Ответ написан
  • Почему так нельзя сделать?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Assembler
    Седой и строгий
    Потому что в процессорах нет инструкции cmp, у которой и первый и второй операнд - это область памяти. Ну, по крайней мере в процессорах с архитектурой x86.
    Ответ написан
    Комментировать
  • Можно ли получить дескриптор файла из памяти?

    С точки зрения системы, динамическая линковка это больше процесс работы со страницами памяти, чем с файлом, он очень похож на работу с файлом подкачки. У процесса нет файловых хэндлов на динамические библиотеки, процесс работает с базовым адресом библиотеки в адресном пространстве. Хэндлы "спрятаны" внутри системы, поэтому подсунуть их в процесс динамической линковки вы не можете. Для динамической линковки недостаточно просто отобразить содержимое файла в память.
    Чтобы реализовать функциональность эквивалентную динамической линковке, вам придется провести процесс динамической линковки вручную: т.е. отобразить нужную часть PE-файла на память, установить для нее необходимые аттрибуты (например пометить код как исполняемый), подгрузить необходимые DLL и заполнить таблицу импорта и вызвать DLLMain. Пример кода, который это делает можно найти, например, здесь:
    https://www.codeproject.com/Tips/430684/Loading-Wi...
    При этом, возможно, придется обходить какие-либо дополнительные защитные механизмы в новых версиях Windows и объяснять антивирусам что у вас нет плохих намерений.

    Если хочется исключить именно операцию открытия файла, и при этом не жалко память - можно выделить память и скопировать содержимое "псевдо-DLL" в буфер памяти из .data вместо отображения файла в память. Использовать имеющееся отображение .data в памяти чтобы провести динамическую линковку непосредственно в нем не получится.
    Ответ написан
    1 комментарий
  • Почему эти строчки записываются в память по-разному?

    @zedxxx
    Потому что в Си, вот эта последовательность "\r" - это управляющая последовательность и в память она записывается как 0xd (один байт). Эту работу выполняет компилятор.

    А в ассемблере как вы строку записали, так она в памяти и лежит, т.е. там символ "\" лежит как 0x5с, и так же лежит рядышком символ "r". Но для HTTP запроса нужен именно перевод строки (последовательность 0xd, 0xa), а не текст "\r".
    Ответ написан
    4 комментария
  • Почему не соединиться с сервером?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я смотрю сюда, и сдаётся мне, что начало инициализации sockaddr_in в твоём коде должна выглядеть так:

    mov byte [sockaddr_in + 0], AF_INET ; sin_family
    mov byte [sockaddr_in + 2], 0 ; sin_port[0] это старший байт sin_port
    mov byte [sockaddr_in + 3], 80 ; sin_port[1] а это младший

    Т.е. перепутана endianness sin_family и sin_port. sin_addr вроде нормально выглядит.
    Ответ написан
    1 комментарий
  • Сколько будут занимать места параметры в данном случае?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ума не приложу, почему размер void _stdcall foo(short a, short b); параметров равен 8

    Потому что аргументы размером меньше 4 байт расширяются до 4 байт. См.

    Как выяснилось, стек растет не только на 4 байта, а на 2.

    То, что в стек физически можно положить 2 байта (а можно ведь и 1, и 3 -- sub $imm, %esp) не означает, что это следует делать. См:
    The stack will always be maintained 16-byte aligned, except within
    the prolog (for example, after the return address is pushed), and except where
    indicated in Function Types for a certain class of frame functions
    Для венды на x86 я такого описания на том же сайте не нашёл, но точно выравнивание должно быть не меньше 4.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти по слову?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Разобраться с вопросом тебе поможет статья: Расставим точки над структурами C/C++.
    Если точнее, то тебе стоит детально изучить первый же пункт статьи: Выравнивание полей памяти.
    В общем выравниваются в памяти поля по границе кратной своему же размеру. То есть 1-байтовые поля не выравниваются, 2-байтовые — выравниваются на чётные позиции, 4-байтовые — на позиции кратные четырём и т.д.
    Ответ написан
    1 комментарий
  • Зачем нужно выравнивание памяти по слову?

    WNeZRoS
    @WNeZRoS
    В подтверждение слов Rsa97 и zedxxx могу привести код на godbolt.
    Там выбрана архитектура ARM, так как там хорошо видно разницу из-за его простоты.

    В жёлтом блоке ассемблерного кода происходит побайтовое чтение поинтера из байт 3, 4, 5, 6 и его склеивание, т.к. отключено выравнивание.
    В голубом блоке происходит чтение сразу всего поинтера потому что он выровнен.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти по слову?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я не знаю, можно ли такого уровня детали найти для современных процессоров, а вот для i80386 в спецификации, в разделе 5.3.6 легко можно видеть, что невыравненный доступ к памяти занимает два цикла, вместо одного.
    За пределами мира x86 многие процессоры вообще не поддерживают доступ к невыравненным данным на аппаратном уровне.
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти по слову?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Большинство современных процессоров читают данные из памяти не отдельными байтами, а блоками по 2-4-8 байт. Соответственно, если у вас данные не выравнены в памяти и начало попадает в один блок, а конец в другой, то для чтения надо будет получить два таких блока.
    Ответ написан
    8 комментариев
  • Почему тут такой mangling?

    petermzg
    @petermzg
    Самый лучший программист
    Calling conventions таблица 21.
    Говориться, что это число указывает суммарное количество байт для всех параметров помещенное в стек
    А в стек вы можете поместить минимальное значение равное разрядности платформы.
    Для 32х битной платформы это 4 байта.
    Отсюда следует, что у вас 2 значения минимум по 4 байта. Суммарно 8
    Ответ написан
  • Почему в windows два формата статических библиотек?

    Zoominger
    @Zoominger Куратор тега Windows
    System Integrator
    .a is an archive of code: compiled but not linked. You would link statically with it during your program's final link step.

    .lib can be either the same as .a, or a magical so-called "import library": a thin placeholder which causes you to require a .dll at runtime.


    https://stackoverflow.com/questions/2337949/whats-...
    Ответ написан
    2 комментария
  • Почему есть смысл в вычитании из ESP?

    freeExec
    @freeExec
    Участник OpenStreetMap
    Достаточно подебажить какой-нибудь HelloWorld и сразу становится понятно, где в стеке лежат аргументы, а где локальные переменные.
    Там же ничего нет?

    На это и расчёт, там нечего испортить, поэтому можно положить на время своё.
    Ответ написан
    Комментировать
  • Где в linux искать библиотеки для GCC?

    vt4a2h
    @vt4a2h Куратор тега C++
    Senior software engineer (C++/Qt/boost)
    Можно установить утилиту locate, и искать всё что вашей душе угодно. Можно посмотреть в пакетном менеджере куда и что устанавливается. Но обычно, компилятор видит библиотеки, установленные по дефолту (в места по-умолчанию), вам надо только -l и имя библиотеки добавить во флаги линкера.
    Ответ написан
    Комментировать
  • Где в linux искать библиотеки для GCC?

    @Alexander1705
    Библиотеки обычно устанавливают в /usr/lib/, /usr/local/lib и их подпапки. Обычно эти пути и так находятся в LD_PATH, так что достаточно указать -l<libname>.

    Так же библиотеки часто устанавливаются вместе с pkg-config конфигурацией, так что можно использовать его так:
    gcc -c file.c `pkg-config --cflags <libname>`
    gcc file.o -o file `pkg-config --libs <libname>`
    Ответ написан
    Комментировать
  • Что подразумевается под "атрибутом вершины"?

    Ni55aN
    @Ni55aN
    Атрибут это и есть отдельный вектор (один из) вершины.
    Ответ написан
    3 комментария
  • Почему тут undefined reference?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Подскажите пожалуйста, почему так

    Потому что порядок перечисления библиотек важен: в списке библиотек a b c символы, которые нужны библиотеке b будут искаться только в библиотеке c, но не в a. Если между библиотеками нет циклических зависимостей (т.е. нет такого, что a определяет символ, нужный b, а b определяет символ, нужный a), то их можно упорядочить так, что линковка будет успешной (см. топологическая сортировка). Если циклические зависимости есть, или сортировать лень, можно перечислить нужные библиотеки несколько раз или взять их в группу:
    g++ main.cpp -Wl,--start-group -lglfw3 -lgdi32 -lopengl32 -lglew32s -Wl,--end-group
    Ответ написан
    Комментировать