Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 May 1996 11:45:00 +0200 (MET DST)
From:      J Wunsch <j@uriah.heep.sax.de>
To:        freebsd-hackers@freebsd.org (FreeBSD hackers)
Subject:   Re: unix + asm
Message-ID:  <199605260945.LAA01614@uriah.heep.sax.de>
In-Reply-To: <Pine.BSF.3.91.960525231529.6761A-100000@onyx.nervosa.com> from "Chris J. Layne" at "May 25, 96 11:16:17 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
As Chris J. Layne wrote:

> > Of course, all this raises the question: why do you wanna do this?

> Uhh, so I can try ASM on my unix machine, is their something wrong with 
> that? =)

The only thing that's wrong is that you'll only need it in < 1 % of
all your time (except you're going to debug and optimize locore.s --
but you might be too late, Poul-Henning already did this recently :).

> I just was curious as to what the diffs were between intel asm 
> and at&t asm.

Everything is just ``a bit different''.  The operators are in the
`right' order, i.e.

	mov	$0, %eax	``move number 0 into register eax''

as opposed to Intel (Microsloth?):

	mov	eax, 0		``move eax into 0'' ??? :)

Many things in the microsloth assemblers are implicit, like operand
size, or indirectness of the operand (0 in the above example), and you
fairly often need to override the assembler's idea (which is
particular fun if you need to override something for both operands).

The unix assembler makes more things explicit.  Direct values are
always prepended with $.  Register names start with % (at least for us
on the i386), so they don't clash with other names.  Operand sizes are
appended to the operation name, as in ``movb'', though this is
optional (i think) if one of the operands is fixed in its size (%eal).

Number notation is C-like (with 0x or 0 prefixes where required), as
is string notation (.ascii "This is an entire line\n").  To get C
strings, you need .asciz, which appends the \0 byte.

Labels are ``static'' implicitly.  Global labels need to be declared.
Note that the C compiler prepends an underscore to each name, so you
need to care for this when interacting with C.  ``Local labels'' are
simple numbers, and are referenced by their number with an `f` or `b'
appended, meaning ``jump forward'' or ``jump backward''.

Offset-indirect addressing is expressed as `offset(%register)'.  There
are more obnoxious variants for the i386 i don't remember right now
(like specifying the operand size, so the CPU multiplies the offset).

A small example.  Store it as foo.s, and pass it to cc along with some
C main() that calls it.  (.s means ``assembler, don't pipe through
cpp'', .S means ``assembler, pipe through cpp''.)

# we don't have .rodata in a.out, so put this into .text
.text
false:	.asciz	"False"
true:	.asciz	"True"

.text
.globl	_btos
#
# const char *
# btos (int b);
#
# /* Boolean to string */
#
_btos:
	# standard prologue: create stack frame
	pushl	%ebp
	movl	%esp, %ebp

	# for demonstration: create local variable, and copy the
	# function arg to it
	subl	$4, %esp
	movl	8(%ebp), %eax		# i386 needs scratch reg for stack copy
	movl	%eax, -4(%ebp)		# 0(%ebp) is the old frame pointer
					# 4(%ebp) is the return %eip
					# 8(%ebp) is the first function arg
					#         (leftmost in C notation)
					# -4(%ebp) is the first local var

	movl	-4(%ebp), %eax
	testl	%eax, %eax
	jnz	1f
	movl	$false, %eax		# %eax is return value
	jmp	2f

1:	movl	$true, %eax
2:
	# function epilogue, clear stack frame
	leave
	ret

-- 
cheers, J"org

joerg_wunsch@uriah.heep.sax.de -- http://www.sax.de/~joerg/ -- NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)



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