Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 Jun 2000 17:20:03 -0700 (PDT)
From:      "Thomas M. Sommers" <tms2@mail.ptd.net>
To:        freebsd-doc@freebsd.org
Subject:   Re: docs/17521: Proposed FAQ on assembly programming
Message-ID:  <200006220020.RAA96491@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR docs/17521; it has been noted by GNATS.

From: "Thomas M. Sommers" <tms2@mail.ptd.net>
To: freebsd-gnats-submit@FreeBSD.org
Cc: alex@big.endian.de
Subject: Re: docs/17521: Proposed FAQ on assembly programming
Date: Wed, 21 Jun 2000 20:17:29 -0400

 Here is an SGML version.  It requires the entities in docs/19425.
 
 	  <qandaentry>
 		<question>
 		  <para>How do I write "Hello, world" in FreeBSD assembler?</para>
 		</question>
 		<answer>
 		  <para>This program prints "Hello, world." on the standard
 		  output, and then exits with an exit status of 0.  It is
 		  written for Intel machines, to be assembled by the GNU
 		  assembler, <command>as</command>.  The syntax used by
 		  <command>as</command> is different from Intel's, but is common
 		  in the Unix world. See &man.as.1; or <command>info
 		  as</command> for details.  This syntax is known as AT&amp;T
 		  syntax.  The most important difference for present purposes is
 		  that the order of operands is reversed: the source operand
 		  comes first, then the destination.  In addition, a size suffix
 		  is appended to the opcodes.</para>
 
 		  <para>The program works by first calling &man.write.2; to write the
 		  message, and then calling &man.exit.2; to exit.</para>
 
 <programlisting>
  1:         .data                       # Data section
  2: 
  3: msg:    .asciz "Hello, world.\n"    # The string to print.
  4:         len = . - msg - 1           # The length of the string.
  5:     
  5:         .text                       # Code section.
  6:         .global _start
  7:
  8: _start:                             # Entry point.
 10:         pushl   $len                # Arg 3 to write: length of string.
 11:         pushl   $msg                # Arg 2: pointer to string.
 12:         pushl   $1                  # Arg 1: file descriptor.
 13:         movl    $4, %eax            # Write.
 14:         call    do_syscall
 15:         addl    $12, %esp           # Clean stack.
 16:
 17:         pushl   $0                  # Exit status.
 18:         movl    $1, %eax            # Exit.
 19:         call    do_syscall
 20:
 21: do_syscall:   
 22:         int     $0x80               # Call kernel.
 23:         ret</programlisting>				
 
 		  <para><literal>_start</literal> (line 8) is the default name
 		  for an ELF program's entry point.</para>
 
 		  <para>Arguments to system calls are placed on the stack from
 		  right to left, just as in C.  Lines 10 through 12 push the
 		  arguments for &man.write.2; on the stack, and line 17 pushes
 		  the argument for &man.exit.2;.  The caller is responsible for
 		  cleaning up the stack after control has returned from the
 		  <literal>call</literal>.</para>
 
 		  <para>System calls are made by putting the call's index in
 		  <literal>%eax</literal> (lines 13 and 18), and invoking
 		  <literal>int $0x80</literal> (line 22).  The kernel expects to
 		  find the first argument 4 bytes below the top of the stack, as
 		  it would be if the system call were made using the C library.
 		  Therefore, the invocation of <literal>int $0x80</literal> is
 		  placed in its own function.</para>
 
 		  <para>The kernel puts the system call's return value in
 		  <literal>%eax</literal>.  If there is an error, the carry flag
 		  is set, and <literal>%eax</literal> contains the error code.
 		  This program ignores the value returned by
 		  &man.write.2;.</para>
 
 		  <para>Assuming you saved the program as <filename>hello.s</filename>,
 		  assemble and link it with:</para>
 
 <screen>&prompt.user; <userinput> as -o hello.o hello.s</userinput>
 &prompt.user; <userinput>ld -o hello hello.o</userinput></screen>
 
 		  <para>It is also possible to invoke system calls using the C
 		  library instead of using <literal>int
 		  $0x80</literal>.</para>
 
 <programlisting>
  1:         .data
  2:
  3: msg:    .string "Hello, world.\n"
  4:         len = . - msg - 1       
  5:
  6:         .text
  7:         .extern write
  8:         .extern exit
  9:         .global main
 10:
 11: main:
 12:         pushl   $len
 13:         pushl   $msg
 14:         pushl   $1
 15:         call    write
 16:         addl    $12, %esp
 17:
 18:         pushl   $0
 19:         call    exit</programlisting>
 
 		  <para>Since we are linking with the C library, we must also
 		  use the C startup code, which means that the entry point to
 		  our program is now <literal>main</literal> (line 11) instead
 		  of <literal>_start</literal>.  (the <literal>_start</literal>
 		  label is in the C startup code, which does some initialization
 		  and then calls <literal>main</literal>.)</para>
 
 		  <para>The easiest way to assemble and link this program is
 		  through <command>cc</command>, which will take care of linking
 		  in the proper startup modules in the correct order:</para>
 
 <screen>&prompt.user; <userinput>cc -o hello
 hello.s</userinput></screen>
 		
 		  <para>There is a lot of information available about assembly
 		  programming on Intel machines, but little if any of it applies
 		  to FreeBSD specifically.  Most or all Intel assembly books and
 		  Web sites are about programming in an MS-DOS environment.
 		  These books can be useful for a FreeBSD programmer to the
 		  extent that they discuss general principles or the Intel
 		  instruction set, but of course nothing specific to MS-DOS or
 		  the PC BIOS will work under FreeBSD.  There is some material
 		  on the Web concerning assembly programming under Linux, but
 		  even this does not always apply to FreeBSD, because Linux uses
 		  a different protocol for making system calls.</para>
 
 		  <para>Here are some Web links that you might find
 		  useful:</para>
 
 		  <segmentedlist>
 			<seglistitem>
 			  <seg><ulink
 			  url="http://developer.intel.com/design/litcentr/index.htm">;
 			  Intel Manuals</ulink></seg>
 
 			  <seg>Reference manuals for Intel processors can be found
 			  here.</seg>
 			</seglistitem>
 
 			<seglistitem>
 			  <seg><ulink url="http://webster.cs.ucr.edu/">Art of
 			  Assembly Language</ulink></seg>
 			
 			  <seg>A well-regarded and very long (~1500 page) online
 			  textbook for assembly programming in MS-DOS.</seg>
 			</seglistitem>
 
 			<seglistitem>
 			  <seg><ulink url="http://linuxassembly.org/">Linux
 			  Assembly</ulink></seg>
 			
 			  <seg>Assembly programming under Linux.  Some useful
 			  information for FreeBSD programmers, but be wary of the
 			  differences between FreeBSD and Linux.</seg>
 			</seglistitem>
 
 			<seglistitem>
 			  <seg><ulink
 			  url="http://www.web-sites.co.uk/nasm/">NASM</ulink></seg>;
 			
 			  <seg>If you prefer Intel syntax in your assembler, try
 			  NASM.  It is in the FreeBSD ports system.</seg>
 			</seglistitem>
 
 			<seglistitem>
 			  <seg><ulink
 			  url="news:comp.lang.asm.x86">comp.lang.asm.x86</ulink>
 			  <ulink
 			  url="http://www.geocities.com/SiliconValley/Peaks/8600/">Host
 			  page</ulink></seg>
 			
 			  <seg>Contains links to other Intel assembly resources on
 			  the Web.</seg>
 			</seglistitem>
 
 			<seglistitem>
 			  <seg><ulink
                         url="http://www.unix.digital.com/faqs/publications/base_doc/DOCUMENTATION/HTML/ulinkA-PS31D-TET1_html/TITLE.html">;
 			  Alpha Assembly Language Programmer's Guide</ulink></seg>
 			
 			  <seg>Probably useful if you are running FreeBSD on an
 			  Alpha.</seg>
 			</seglistitem>
 
 		  </segmentedlist>
 		</answer>
 	  </qandaentry>
 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-doc" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200006220020.RAA96491>