【问题标题】:undefined reference to WinMain@16未定义对 WinMain@16 的引用
【发布时间】:2013-01-15 03:51:29
【问题描述】:
segment .data

msg db "Enter your ID", 0xA, 0xD
len equ $ - msg

segment .bss

id resb 10

segment .text

global _start

_start:

    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, len
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, id
    mov edx, 10
    int 0x80

    mov eax, 4
    mov ebx, 1
    int 0x80

_exit:

    mov eax, 1;
    xor ebx, ebx
    int 0x80

    ;End

我正在尝试使用 gcc 在 c 中编译此文件,但程序给了我一个错误,我完全不知道问题出在哪里。跟我的操作系统有关系吗?

【问题讨论】:

    标签: nasm


    【解决方案1】:

    您的代码不应使用标准 C 库,因此将其与裸 ld 链接而不是 gcc 会有所帮助(_start 是默认的入口点,可以使用 --entry 选项指定其他入口点为ld)。

    但这无济于事:此代码不适用于 Windows 操作系统,您显然是在为 Windows 编译它。

    【讨论】:

    • 嗯,有什么办法可以在 Windows 上编译它吗?
    • 你必须重写它(syscall / int80h 接口是特定于操作系统的,如果在 Windows 上一个指定的系统调用 ABI,它就是一个不同的 ABI。大多数可能你必须调用 winapi 函数,这很容易,但如果你想用“没有 C 的纯程序集”编写,这有点违背了目的)
    • 有什么我可以下载的 linux 模拟器吗?
    • 你可以看看colinux.org。或者您可以在任何您喜欢的虚拟机中设置 Linux(例如virtualbox.org
    【解决方案2】:

    这个程序只能在 32 位 Linux 中运行。 这个程序仍然存在问题。

    将“_start”更改为“main” 此外,系统调用后可能不会保留 ecx 和 edx (int 0x80)

    请尝试以下示例。

    组装和链接:
    nasm -felf hello.asm
    gcc -o 你好你好.o

    segment .data
    
    msg db "Enter your ID", 0xA
    len equ $ - msg
    
    segment .bss
    
    id resb 10
    
    segment .text
    
    global main
    
    main:
    
        mov eax, 4
        mov ebx, 1
        mov ecx, msg
        mov edx, len
        int 0x80
    
        mov eax, 3
        mov ebx, 0
        mov ecx, id
        mov edx, 10
        int 0x80
    
        mov edx, eax  ;; length of the string we just read in.
        mov eax, 4
        mov ebx, 1
        mov ecx, id
        int 0x80
    
    _exit:
    
        mov eax, 1;
        xor ebx, ebx
        int 0x80
    
        ;End
    

    【讨论】:

      【解决方案3】:

      对于 Windows,如果您可以使用 C 库,请尝试此示例。

      ;;Assemble and link with
      ;nasm -fwin32 hello.asm
      ;gcc -o hello hello.obj
      
      global _main 
      extern _scanf 
      extern _printf     
      
      segment .data
      
          msg: db "Enter your ID", 0xA, 0xD, 0  ; note the null terminator.
          formatin: db "%s", 0                  ; for scanf.
      
      segment .bss
          id resb 10
      
      segment .text
      
      _main:
      
         push msg
         call _printf
         add esp, 4 
      
         push id  ; address of number1 (second parameter)
         push formatin ; arguments are pushed right to left (first parameter)
         call _scanf
         add esp, 8 
      
      
         push id
         call _printf
         add esp,4              
      
         ret  
      

      【讨论】:

        【解决方案4】:

        我知道这是一个老话题,但我一直有这个问题,想澄清一下。

        您需要将_start 更改为_main。我相信这是这样 NASM 可以正确组装您的文件,用 _main 替换对 WinMain@16 的引用,以便 MinGW 可以成功链接它

        另外,int 0x80 是一个 LINUX 系统调用。也许改用call _printf,并将extern _printf 放在程序的顶部。

        【讨论】:

          猜你喜欢
          • 2021-11-18
          相关资源
          最近更新 更多