Hello
The 64-bit gcc procedure prolog pushes registers onto the stack in a
manner that is different from the 32-bit gcc version.
Furthermore, this appears to be unique to Cygwin64, and this does not
happen on Linux.
This shows up when you use __builtin_frame_address(n) and
__builtin_return_address(n).
This is illustrated with the attached C++ program. If the local
variables in the sub() procedure are designated as register variables,
the sub procedure does not find the frame address and return address of
the caller (main). If these variables are not designated a register
variables, the sub procedure does find and print the correct values.
If you look at the generated code (-S option), you can see that the
64-bit versions pushes the saved registers onto the stack before the
frame pointer is updated, while the 32-bit version pushes the saved
registers onto the stack after the frame pointer is updated.
64-bit version
.seh_proc _Z3subv
_Z3subv:
.LFB7:
pushq %rbp
.seh_pushreg %rbp
pushq %rdi
.seh_pushreg %rdi
pushq %rsi
.seh_pushreg %rsi
pushq %rbx
.seh_pushreg %rbx
movq %rsp, %rbp
.seh_setframe %rbp, 0
subq $40, %rsp
32-bit version
.def __Z3subv; .scl 2; .type 32; .endef
__Z3subv:
LFB7:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %edi
pushl %esi
pushl %ebx
subl $28, %esp
Herb Schwetman
Mesquite Software, Inc.
---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
// testbuiltin.cpp
#include <stdio.h>
void sub()
{
register int a, b, c;
// int a, b, c;
printf("\nsub\n");
printf("frame address %016llx\n", __builtin_frame_address(0));
printf("return address %016llx\n", __builtin_return_address(0));
printf("frame address caller %016llx\n", __builtin_frame_address(1));
printf("return address caller %016llx\n", __builtin_return_address(1));
a = 1; b = 2; c = 3;
printf("a %d, b %d, c %d\n", a, b, c);
}
int main()
{
int a, b, c;
printf("frame address %016llx\n", __builtin_frame_address(0));
printf("return address %016llx\n", __builtin_return_address(0));
a = 1; b = 2; c = 3;
printf("a %d, b %d, c %d\n", a, b, c);
sub();
return 0;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple