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>