Связывание 64-битного «Hello, world» для окон с использованием winapi - PullRequest
0 голосов
/ 25 января 2019

Недавно я просто пытался изучить некоторую сборку и подумал, что Nasm будет хорошим выбором, так как я более привык к его intel_syntax. В любом случае, после преднамеренной попытки найти примеры программ для 64-битной Windows, я обнаружил этот SO пост и попытался использовать код, предоставленный во втором ответе. Единственное, что код был для x86 windows, который не является моей целевой платформой. Поэтому я попытался написать программу для 64-битной Windows (обратите внимание на слово попыталось ). Я довольно новичок в Assembly, поэтому мой код, скорее всего, неверен, и я был бы признателен, если бы кто-то указывал на такие ошибки.

Однако проблема, с которой я столкнулся, связана с линковкой. По какой-то причине, когда я пытаюсь связать объектный файл, компоновщик gcc не может разрешить внешние символы (т.е. функции winapi), и я не могу понять, почему он это делает.

Вот мой код (я прокомментировал каждую строку, чтобы попытаться понять, что делает программа, но, пожалуйста, не стесняйтесь редактировать этот пост и изменить что-либо, если оно не так).

section .text               ;Section of the src file that contains the actual runtime code
global WinMain@16           ;Makes the address WinMain global. @16 signifies 16 bytes of parameters

extern  _GetStdHandle@4     ;Assures compiler of an external definition of the declared function 'GetStdHandle()'
extern  _WriteFile@36       ;Assures compiler of an external definition of the declared function 'WriteFile()'
extern  _ExitProcess@4      ;Assures compiler of an external definition of the declared function 'ExitProcess()'

WinMain@16:                 ;Label marking the entry-point of the program (Windows expects 'WinMain' unless explicitly specified)
    mov rbp, rsp            ;Move Stack Pointer value equal to Base Pointer
    sub rsp, 4              ;Move Stack Pointer back (i.e. subtract) 4 bytes to store DWORD '-11' (defined by 'STD_OUTPUT_HANDLE')

    push -11                ;Push '-11' into stack
    call _GetStdHandle@4    ;Calls GetStdHandle(-11) since -11 has been pushed. @4 signifies 4 bytes of parameters
    mov rbx, rax            ;rax stores return value -> move that value to rbx

    push 0                  ;Push 0 (NULL) onto the stack (This is the last argument in the function)
    lea rax, [rbp - 4]      ;Store address of DWORD in rax register (4 byte value, 8 byte pointer)
    push rax                ;Push address of DWORD as the next parameter
    push (msg_end - msg)    ;Push number of bytes to write (3rd parameter)
    push msg                ;Push pointer to constant data bytes (2nd parameter)
    push rbx                ;Push value stored in 'rbx' (The HANDLE) into the 1st parameter
    call _WriteFile@36      ;Calls WriteFile(hStdOut, msg, msg_len, bytes_written, NULL). @36 signifies 36 bytes of parameters

    push 0                  ;Push 0 onto the stack (parameter)
    call _ExitProcess@4     ;Calls ExitProcess(0) and ends the program. @4 signifies 4 bytes of parameters

                ; ---- << Nothing gets called a beyond this line >> ---- ;

    hlt                     ;I have no clue why you need to halt here
    msg:                    ;Label marking the start of the message
        db "Hey world", 10  ;Actual data, (db = define bytes). "Hey world" and 10 (new-line character)
    msg_end:                ;Label marking the end of the message

Для компиляции я запускаю следующее

nasm -f win64 Main.asm -o Main.bin

и для связи я запускаю это и получаю следующий вывод ...

gcc -o Hello.exe Main.o
bin/Main.o:src/Main.asm:(.text+0xa): undefined reference to `_GetStdHandle@4'
bin/Main.o:src/Main.asm:(.text+0x21): undefined reference to `_WriteFile@36'
bin/Main.o:src/Main.asm:(.text+0x28): undefined reference to `_ExitProcess@4'
collect2.exe: error: ld returned 1 exit status

Как видите, он не может связываться с внешними функциями. Интересно то, что он прекрасно работает, когда я пытаюсь вызывать функции 'c', такие как 'put'

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

...