Other Difference between "as" and "ld" on BSD vs Linux (assembly)?

I started reading "Programming from the Ground Up", a free programming book that starts new programmers with assembly, and the first two example programs that I've tried so far didn't run correctly on FreeBSD (but worked on Fedora).

These simple programs store a calculation in an exit code which you can check after running the program. They were exit.s and maximum.s from this page https://github.com/foomur/programming-ground-up
The first program's exit code is supposed to be 0, and the second's 222.
On FreeBSD the first program exited with 64 (in /usr/include/sysexits.h this is defined as: #define EX_USAGE 64 /* command line usage error */ ) and the second with 13.
This is while simply running:
as exit.s -o exit.o
ld exit.o -o exit
./exit
echo $?

..and similar for maximum.s

Any hints about what I need to change for this book to work on BSD?

Edit: Ok now looking at chapter 11 of the handbook I see there could be some significant differences between Linux and BSD. Not like the first programming language I learned and have been using casually for a few years on both, the bourne shell! Silly me.
 
I'll give you a general idea about assembly in FreeBSD.
First, you have to look at FreeBSD Developers' Handbook | x86 Assembly Language Programming. You have to follow FreeBSD conventions.
Then, here is some basic example to write assembly language in FreeBSD for amd64. I hope, It give you some ideas:

Using fasm lang/fasm:

File: fasm.s

Code:
format ELF executable
entry _start

segment readable executable
_start:
  push  len
  push  msg
  push  1
  mov   eax, 0x4
  push  0
  int   0x80

  xor   eax, eax
  int   0x80

segment readable writable
  msg db "fasm", 0x0a
  len = $-msg
fasm fasm.s
brandelf -t FreeBSD fasm
chmod 755 fasm && ./fasm

Output:
Code:
fasm

Using as(1):

File: gas.s

Code:
.global _start
.text
_start:
    mov $1, %rax
    mov $1, %rdi
    mov $msg, %rsi
    mov $4, %rdx
    syscall
    mov $60, %rax
    xor %rdi, %rdi
    syscall
msg:
    .ascii "gas\n"

cc -c gas.s
ld gas.o -o gas.out
brandelf -t linux gas.out
./gas.out

Output:
Code:
gas

Using as32 on 64 machine as(1):

File: gas32.s

Code:
.file   "gas32.s"
  .extern printf
  .data

msg:
  .ascii "gas\n"
  .text
  .globl main

main:
  pushl %ebp
  movl  %esp, %ebp
  pushl $msg

  call output_message
  movl  $0, %eax
  leave
  ret

output_message:
  pushl %ebp
  movl  %esp, %ebp
  subl  $8, %esp
  movl  8(%ebp), %eax
  movl  %eax, (%esp)
  call  printf
  addl  $4, %esp
  movl  $0, %eax
  leave
  ret $4

cc -m32 -o gas32.out gas32.s
./gas32.out

Output:
Code:
gas

using nasm (from the handbook) devel/nasm:
Here, we have 2 files: nasm.s and nasm.inc

File 1:nasm.s

Code:
%include    'nasm.inc'
section    .data
msg    db    'nasm', 0Ah
hbytes    equ    $-msg

section    .text
global    _start
_start:
push    dword hbytes
push    dword msg
push    dword stdout
sys.write

push    dword 0
sys.exit

File 2: nasm.inc

Code:
%define    stdin   0
%define    stdout  1
%define    stderr  2

%define    SYS_nosys    0
%define    SYS_exit    1
%define    SYS_fork    2
%define    SYS_read    3
%define    SYS_write    4

section    .text
align 4
access.the.bsd.kernel:
  int    80h
    ret

%macro    system    1
    mov    eax, %1
    call    access.the.bsd.kernel
%endmacro

%macro    sys.exit    0
    system    SYS_exit
%endmacro

%macro    sys.fork    0
    system    SYS_fork
%endmacro

%macro    sys.read    0
    system    SYS_read
%endmacro

%macro    sys.write    0
    system    SYS_write
%endmacro

nasm -f elf nasm.s
ld -s -o nasm.out nasm.o
brandelf -t freebsd nasm.out
./nasm.out

Output:
Code:
nasm

using __asm__ in C language:

File: casm.c

C:
#include <stdio.h>
int
main()
{
  int var;
  __asm__ (
  "movl %%eax, %%ebx;" : "=a" (var) : "a" (0x63)
  );
  printf( "%c%c\n", var, var+0x10 );
  return 0 ;
}

cc -o casm.out casm.c
./casm.out

Output:
Code:
cs
 
I'll give you a general idea about assembly in FreeBSD.

This is a great post. Thanks for putting it out here. I am curious, is there a cultural preference within the FreeBSD community as to which assembler to use. I've seen nasm a lot, and it's in the handbook, but is that really the preferred tool/syntax?
 
  • Thanks
Reactions: a6h
The assembly code inside FreeBSD is written with as (AT&T syntax). Personally, I was accustomed to the Intel syntax (FASM, NASM and others), maybe due to my Microsoft Windows background. But, it takes a couple of minutes to pass from one to another.

To the OP: programing FreeBSD with Linux in mind is the best way to make all fails.
 
Back
Top