Программирование с помощью NASM в Windows XP

У меня есть следующий код, который собирается и отлично работает на 32-битной Windows XP, 2.09.08 NASM:

; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o

section .data

section .text

;global _WinMain@16
;_WinMain@16:

;global _start
_start:
    mov ax,4           

    jmp $

Согласно многим учебным пособиям по NASM для файла asm необходимо следующее:

global _WinMain@16
_WinMain@16:
...

Как вы можете видеть, в моем asm-файле этого нет. (это закомментировано, все, что у него есть _start). Итак, что же во всех этих руководствах упоминается о необходимости глобального материала _WinMain@16, когда моя программа сборки не имеет этого и работает?

это команда для сборки: nasm -f elf test.asm
это команда для связывания: ld -o test.exe test.o

1 ответ

Решение

В Windows существует несколько типов приложений с разными точками входа в зависимости от того, к какому типу они относятся. Опцией link.exe:

  • /SUBSYSTEM:CONSOLE - требует main и связь с msvcrXX.dll, Эти приложения работают в консольных окнах; если вы не запускаете экземпляр cmd.exe, он будет открыт.
  • /SUBSYSTEM:WINDOWS - WinMain является отправной точкой. Смотрите здесь. Обычно в С эти #include <windows.h> и связаны непосредственно с kernel32.dll, Эти графические приложения и почти наверняка связаны с user32.dll и, возможно, advapi32.dll также.
  • /SUBSYSTEM:NATIVE - здесь есть два типа приложений; драйверы и приложения. Родные приложения NT запускаются во время запуска Windows и требуют NtProcessSStartup в качестве точки входа. В родных приложениях нет libc. Драйверы снова разные.

Полный список поддерживаемых подсистем Windows link.exe доступно здесь.

_start является символом окна на самом деле запустить ваш код на. Обычно, libc или как на самом деле обрабатывает _start и делает некоторые начальные настройки, так что ваша программа на самом деле не совсем начинается с _main, Если вы хотите связаться с libc у вас будут проблемы, поскольку у вас будут конфликтующие символы с библиотекой libc. Однако, если вы никогда не собираетесь вызывать какие-либо функции, которые являются частью стандартных библиотек C или C++, вы можете использовать _start,

Редактировать yikes, я только что заметил это:

; how to compile: nasm -f elf test.asm
; how to link: ld -o test.exe test.o

Я полагаю, вы не используете -f elf один. ELF (исполняемый и линкованный формат) - это формат linux для исполняемых файлов; Для Windows требуются образы Portable Executable (PE). Вариант носа -f win32или для дос nasm -f coff,

Правка 2 просто для проверки, я собрал код и снова разобрал его. Я также использовал Mingw. Во всяком случае, я получил:

SECTION .text   align=16 execute                        ; section number 1, code
Entry_point:; Function begin
; Note: Length-changing prefix causes delay on Intel processors
        mov     ax, 4                                   ; 00401000 _ 66: B8, 0004
?_001:  jmp     ?_001                                   ; 00401004 _ EB, FE
; Entry_point End of function
; Note: Length-changing prefix causes delay on Intel processors
        mov     ax, 4                                   ; 00401006 _ 66: B8, 0004
?_002:  jmp     ?_002                                   ; 0040100A _ EB, FE

Остальная часть заголовка представляется допустимым исполняемым файлом формата PE без указания точки входа. Поэтому я полагаю, что код просто "проваливается" на первый кусок кода сборки для запуска. Я бы не советовал такое поведение, особенно при связывании нескольких объектов, так как понятия не имею, что произойдет. Использовать -entry,

Разбирая объектный файл elf я получаю это:

SECTION .data   align=4 noexecute                       ; section number 1, data
SECTION .text   align=16 execute                        ; section number 2, code
_start_here:; Local function
; Note: Length-changing prefix causes delay on Intel processors
        mov     ax, 4                                   ; 0000 _ 66: B8, 0004
?_001:  jmp     ?_001                                   ; 0004 _ EB, FE
_another_symbol:; Local function 
; Note: Length-changing prefix causes delay on Intel processors
        mov     ax, 4                                   ; 0006 _ 66: B8, 0004
?_002:  jmp     ?_002     

Другими словами, в нем нет конкретных заголовков в формате ELF. Я верю, что тебе повезло в этом; начните импортировать или пытаться связать с другими модулями кода, и все станет сложнее.

Для Windows / MINGW вы хотите:

nasm -f win32 file.asm 

для каждого файла, который вы хотите собрать. Замена win32 за win64 при необходимости. ld подойдет для ссылки.

Просто мысль - я никогда не объяснял @16 часть. Функции в Windows выровнены на 16 байтов, тогда как, как вы можете видеть, данные выровнены только на четыре байта. Смотрите это объяснение почему.

Другие вопросы по тегам