对WinMain @ 16的未定义引用

时间:2013-01-31 05:29:48

标签: nasm

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中编译此文件,但该程序给了我一个错误,我完全不知道问题出在哪里。它与我的操作系统有什么关系吗?

4 个答案:

答案 0 :(得分:1)

该程序仅适用于32位Linux。 该计划仍有问题。

将'_start'更改为'main' 此外,系统调用(int 0x80)

后,可能无法保留ecx和edx

Plz尝试以下示例。

组装&链接:
nasm -felf hello.asm
gcc -o hello hello.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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

对于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  

答案 3 :(得分:0)

我知道这是一个旧帖子,但我一直都有这个问题,并希望澄清它。

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

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