Linking Assembly Code - Can't resolve printf

Eric Blake
Wed Sep 20 13:04:00 GMT 2006

Hash: SHA1

According to David Lariviere on 9/20/2006 1:51 AM:
> The code is actually taken out of "Professional Assembly Language" by
> Richard Blum.

Which is Linux specific.  Don't expect it to work on cygwin, because
cygwin has a different ABI.

> I presume by entry-point your referring to the use of _start instead of
> main. According to the book (I have no way of knowing beyond testing on a
> separate linux box if it is true though), using gcc directly requires "main"
> entrypoint but 'as' expects _start as the default entry-point. 

Careful.  as ALWAYS expects _start, even when it is used by gcc.  The
difference is that gcc automagically links in -lc, which includes crt0.a
(the C runtime), which defines _start and calls main.  Which is why C
programs must define main, not _start.  But if you are going low-level
assembly where you bypass the C library, you lose out on C runtime features.

> In the first piece of code I pasted, I am guessing the 0x80 signal interrupt
> to write to console is a linux only feature that won't somehow get
> translated by cygwin/gcc (I had hoped otherwise, but figured as much). 

0x80 is the x86 trap command, which invokes a syscall.  Linux syscalls are
entirely different (you really are asking the kernel to do something) from
Windows syscalls (not to mention that in cygwin, you don't make raw
syscalls, but let cygwin1.dll do it for you, so your program should NEVER
expect 0x80 to work).  Your program is BOUND to crash if you don't comply
with the ABI of your platform.

> Ignoring 0x80 issue (assuming that was the problem you were alluding), I can
> now get it compiling but not running. Below is an earlier program from the
> same book which doesn't use 0x80. 

Don't ignore the 0x80 issue.  If you don't understand what an ABI is, then
you shouldn't program in assembly.  Use a high-level language like C; it
is what they were invented for.

> #cpuid2.s View the CPUID Vendor ID string using C library calls
> .section .data
> output:
>     .asciz "The processor Vendor ID is '%s'\n"
> .section .bss
>     .lcomm buffer, 12
> .section .text
> .globl _start
> _start:
>     movl $0, %eax
>     cpuid
>     movl $buffer, %edi
>     movl %ebx, (%edi)
>     movl %edx, 4(%edi)
>     movl %ecx, 8(%edi)
>     pushl $buffer
>     pushl $output
>     call printf
>     addl $8, %esp
>     pushl $0
>     call exit
> It now compiles fine, but crashes as soon as it runs. I am hoping it is not
> the entry-point issue, since the same syntax compiled and ran successfully
> on my fedora box. 

Because printf is a C library function, but you overrode _start, so the C
runtime is not initialized properly.  Provide main, not _start, if you
want success (and remember, it might be spelled _main, depending on the C
library of the OS you are targetting).

> In the book, the author says that the program will crash because it is
> necessary to specify the runtime dynamic linker. In the linux platform
> example for which the book targets, it states to use: 
> ld -dyanmic-linker /lib/ -o cpuid2 -lc cpuid2.o

Cygwin uses Windows' dynamic linking, which is ENTIRELY different from
Linux.  Give up now, while you have a chance.

- --
Life is short - so eat dessert first!

Eric Blake   
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at
Comment: Using GnuPG with Mozilla -


Unsubscribe info:
Problem reports:

More information about the Cygwin mailing list