This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
gas, x86-64, Linux vs. FreeBSD/OpenSolaris
- From: Bob Plantz <plantz at cds1 dot net>
- To: binutils at sourceware dot org
- Date: Fri, 30 Jan 2009 14:26:11 -0800
- Subject: gas, x86-64, Linux vs. FreeBSD/OpenSolaris
I am working on x86-64 in 64-bit mode. I'm using gas.
In Linux I can dereference a 32-bit register as shown on the second line
below "whileLoop" in the code below. But when I try to assemble it under
OpenSolaris or FreeBSD (also in 64-bit mode), I have to use the full
64-bit register.
The error message comes from gas. So it's clear that gas has been built
differently for Linux than for the other two systems. Can anyone help me
understand (a) how this is done, and (b) why it is done?
I have also determined that gcc will use a 64-bit pointer if I do
char *ptr = "Hello\n";
while (*ptr != '\0') {
write(1, ptr, 1);
ptr++;
}
but will use a 32-bit register if I do
write(1, "Hello\n", 6);
on both Linux and FreeBSD. (I have not checked this on OpenSolaris.)
My point here is that gcc on both Linux and FreeBSD will use a 32-bit
register if it knows that the address will fit into 32 bits. So why can
I not dereference a 32-bit register in FreeBSD and OpenSolaris, but can
in Linux?
Bob Plantz
# Useful contants
.equ STDOUT,1
# Stack frame
.equ aString,-8
.equ localSize,-16
# Read only data
.section .rodata
theString:
.string "Hello world.\n"
# Code
.text
.globl main
.type main, @function
main:
pushq %rbp # save base pointer
movq %rsp, %rbp # set new base pointer
addq $localSize, %rsp # for local var.
movl $theString, %esi
movl %esi, aString(%rbp) # *aString = "Hello World.\n";
whileLoop:
movl aString(%rbp), %esi # current char in string
#### The following instruction gives an error when assembling with
#### as on OpenSolaris and FreeBSD. It works fine when I change
#### "%esi" to "%rsi" (and make other changes to keep everything
#### consistent).
cmpb $0, (%esi) # null character?
je allDone # yes, all done
movl $1, %edx # one character
movl $STDOUT, %edi # standard out
call write # invoke write function
incl aString(%rbp) # aString++;
jmp whileLoop # back to top
allDone:
movl $0, %eax # return 0;
movq %rbp, %rsp # restore stack pointer
popq %rbp # restore base pointer
ret