This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: which registers must be preserved for the caller
- From: Andrew Makhorin <mao at gnu dot org>
- To: Mason <slash dot tmp at free dot fr>
- Cc: GCC help <gcc-help at gcc dot gnu dot org>
- Date: Tue, 22 Aug 2017 16:16:30 +0300
- Subject: Re: which registers must be preserved for the caller
- Authentication-results: sourceware.org; auth=none
- References: <1503126647.4161.3.camel@corvax> <d0470a4d-db7d-ca69-6906-1124614ae8e1@free.fr>
On Mon, 2017-08-21 at 15:39 +0200, Mason wrote:
> On 19/08/2017 09:10, Andrew Makhorin wrote:
>
> > The document "System V ABI: Intel386 Architecture Processor Supplement"
> > says that contents of %ebx, %esi, and %edi must be preserved for the
> > caller. Does GCC for 32-bit GNU/Linux and for 32-bit Cygwin conform to
> > this ABI? If not, how to determine which registers are expected to be
> > saved by calling C functions?
Thank you for your answer.
>
> (NB: GCC supports dozens of platforms)
>
> You seem to be interested in the x86 "cdecl" ABI.
>
> https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl
The C Standard says nothing about calling conventions, so I meant that
one that is used by default (which is probably cdecl).
>
> I think the SysV and Microsoft ABI are close, but may differ
> over details, e.g. returning structs.
I asked my question, because GCC doesn't seem to follow System V ABI.
In the following example %ebx, %esi, and %edi are not preserved being
clobbered by the generated code.
mao@corvax:~/Desktop/foo$ cat foo.c
int foo(int x[], int y[], int z[], int i, int j, int k)
{
int t;
t = (x[i+j] + y[j+k] + 2) * (z[i+j+k] + 1) * (z[k+1] + 2);
return t;
}
mao@corvax:~/Desktop/foo$ gcc -c -O2 -save-temps foo.c
mao@corvax:~/Desktop/foo$ cat foo.s
.file "foo.c"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
subl $12, %esp
.cfi_def_cfa_offset 16
movl 32(%esp), %eax
movl 36(%esp), %edx
movl %ebx, (%esp)
.cfi_offset 3, -16
movl 28(%esp), %ebx
movl %esi, 4(%esp)
movl 24(%esp), %ecx
movl %edi, 8(%esp)
.cfi_offset 6, -12
.cfi_offset 7, -8
movl 20(%esp), %edi
leal (%eax,%edx), %esi
addl %eax, %ebx
movl 16(%esp), %eax
movl (%eax,%ebx,4), %eax
addl %edx, %ebx
movl (%ecx,%ebx,4), %ebx
addl (%edi,%esi,4), %eax
movl 4(%ecx,%edx,4), %edx
movl 4(%esp), %esi
addl $1, %ebx
addl $2, %eax
movl 8(%esp), %edi
imull %ebx, %eax
movl (%esp), %ebx
addl $12, %esp
.cfi_restore 7
.cfi_restore 6
.cfi_restore 3
.cfi_def_cfa_offset 4
addl $2, %edx
imull %edx, %eax
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.ident "GCC: (Debian 4.7.2-5) 4.7.2"
.section .note.GNU-stack,"",@progbits
mao@corvax:~/Desktop/foo$ gcc --version
gcc (Debian 4.7.2-5) 4.7.2