public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 64-bit write() system call
@ 2008-03-20  0:19 Bob Plantz
  2008-03-20  2:00 ` Brian Dessent
  0 siblings, 1 reply; 3+ messages in thread
From: Bob Plantz @ 2008-03-20  0:19 UTC (permalink / raw)
  To: gcc-help

First, I have also posted this on ubuntuforums.org. I know that's bad
form, but I don't think there will be many cross-readers here.

The default address size is 64 bits in 64-bit mode. But when I look at
the assembly language for the write() syscall, gcc uses only 32 bits of
the address:

	.file	"oneChar.c"
	.data
	.type	aLetter, @object
	.size	aLetter, 1
aLetter:
	.byte	65
	.text
.globl main
	.type	main, @function
main:
	pushq	%rbp             // <== 64-bit addresses
	movq	%rsp, %rbp       // <==
	movl	$1, %edx
	movl	$aLetter, %esi   // <== 32-bit address
	movl	$1, %edi
	call	write
	movl	$0, %eax
	leave
	ret
	.size	main, .-main
	.ident	"GCC: (GNU) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
	.section	.note.GNU-stack,"",@progbits

Can anyone point me to discussions of what is going on here?

Bob


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: 64-bit write() system call
  2008-03-20  0:19 64-bit write() system call Bob Plantz
@ 2008-03-20  2:00 ` Brian Dessent
  2008-03-20  6:11   ` Bob Plantz
  0 siblings, 1 reply; 3+ messages in thread
From: Brian Dessent @ 2008-03-20  2:00 UTC (permalink / raw)
  To: Bob Plantz; +Cc: gcc-help

Bob Plantz wrote:

> The default address size is 64 bits in 64-bit mode. But when I look at
> the assembly language for the write() syscall, gcc uses only 32 bits of
> the address:

The design of the x86_64 instruction set made some compromises for speed
and for keeping the size of the instructions down, namely that there are
very few instructions that take a full 64 bit operand... in fact
'movabs' is the only one.  All the rest all take 32 bit operands and the
address is calculated through either sign extension or as
%rip-relative.  This is actually not a big deal because these days most
linking is done with shared libraries, and so you already have a level
of indirection there with the PLT/GOT so it doesn't matter that much
that it's awkward to refer to an absolute 64 bit address -- turns out
this isn't a very common thing to need to do.

If you read the x86_64 ELF document there are a number of different code
models defined: small, medium, large, and kernel, corresponding to the
gcc switch "-mcmodel=".  The small model is the default and to quote the
ELF document:

> The virtual address of code executed is known at link time. Additionally 
> all symbols are known to be located in the virtual addresses in the 
> range from 0 to 2**31 - 2**24 - 1 or from 0x00000000 to 0x7effffff. 
> This allows the compiler to encode symbolic references with offsets in 
> the range from -(2**31) to 2**24 or from 0x80000000 to 0x01000000 
> directly in the sign extended immediate operands, with offsets in the 
> range from 0 to 2**31 - 2**24 or from 0x00000000 to 0x7f000000 in the 
> zero extended immediate operands and use instruction pointer relative 
> addressing for the symbols with offsets in the range -(2**24) to 2**24 
> or 0xff000000 to 0x01000000. This is the fastest code model and we 
> expect it to be suitable for the vast majority of programs.

Because of these assumptions, the reference to your aLetter symbol can
be handled with a simple 32 bit reloc (R_X86_64_32) which is defined as
truncating the address into 32 bits.  This combines with the fact that
the processor zero extends 32 bit operations with register destinations,
so when the value of that reloc is loaded into %esi the upper 32 bits of
%rsi are implicitly set to zero.  This also has an advantage for library
calls like your call to write(), since %rip-relative addressing mode can
cover the whole available address space -- the call will be be resolved
with a R_X86_64_PLT32 reloc.

The end result is 64 bit addressing without paying the price of wider
opcodes or more complicated relocs, it's really a win-win.  Of course
for those apps that really need more arbitrary addressing, it's
available in the other models, but this way the common case doesn't have
to pay the price.

Brian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: 64-bit write() system call
  2008-03-20  2:00 ` Brian Dessent
@ 2008-03-20  6:11   ` Bob Plantz
  0 siblings, 0 replies; 3+ messages in thread
From: Bob Plantz @ 2008-03-20  6:11 UTC (permalink / raw)
  To: gcc-help


On Wed, 2008-03-19 at 18:59 -0700, Brian Dessent wrote:
> The design of the x86_64 instruction set made some compromises for speed
> and for keeping the size of the instructions down, namely that there are
> very few instructions that take a full 64 bit operand... in fact
> 'movabs' is the only one.  All the rest all take 32 bit operands and the
> address is calculated through either sign extension or as
> %rip-relative.  This is actually not a big deal because these days most

I read that, but then how can I do the 64-bit immediate here:

  11 0004 49BAEFCD 	        movq    $0x1234567890abcdef, %r10  # 64-bit
immediate
  11      AB907856 
  11      3412
  12 000e 41BB7856 	        movl    $0x12345678, %r11d         # 32-bit
immediate
  12      3412
  13 0014 6641BC34 	        movw    $0x1234, %r12w             # 16-bit
immediate
  13      12
  14 0019 41B512   	        movb    $0x12, %r13b               # 8-bit
immediate

Thank you for your quote from x86_64 ELF. It's making sense to me now. I
guess I jumped the gun a little when posing my question. I should've
read some more. But I was getting stuck in my research trying to figure
out what to read. You've helped me a great deal.

Bob


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-03-20  6:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-20  0:19 64-bit write() system call Bob Plantz
2008-03-20  2:00 ` Brian Dessent
2008-03-20  6:11   ` Bob Plantz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).