error: bp cannot be used in asm here
Posted: Wed Jun 04, 2025 12:32 pm
Hi all,
today I got burned on GCC a little, and I think venting might help me sleep later.
Today I did a few build tests with my libc implementation, and I got the above curious error message when compiling this function for i386:
What is curious is that I only get an error if optimization is disabled. Googling the message turned up that if GCC decides to compile the function with frame pointer, then EBP is off limits. Of course, on i386, GCC works without frame pointers most of the time, as long as any optimization is on, really. So it will accept the above code only conditional on optimization level.
I have now added a compile test and a workaround: If the compiler is found to not like ebp in assembler, then the above assembly is turned instead into
which the compiler thankfully accepts. Though I do wonder if my test will eventually fail when the compiler decides to enable frame pointers for only some of the time.
I would be somewhat willing to forgive the quirkiness if the compiler was a little bit older. But no, this is with GCC 12, the thing that's currently shipped with Debian.
today I got burned on GCC a little, and I think venting might help me sleep later.
Today I did a few build tests with my libc implementation, and I got the above curious error message when compiling this function for i386:
Code: Select all
static inline long __syscall6(long nr, long a, long b, long c, long d, long e, long f)
{
register long eax __asm__("eax") = nr;
register long ebx __asm__("ebx") = a;
register long ecx __asm__("ecx") = b;
register long edx __asm__("edx") = c;
register long esi __asm__("esi") = d;
register long edi __asm__("edi") = e;
register long ebp __asm__("ebp") = f;
__asm__ volatile("calll *%%gs:16" : "+r"(eax) : "r"(ebx), "r"(ecx), "r"(edx), "r"(esi), "r"(edi), "r"(ebp) : "memory");
return eax;
}
I have now added a compile test and a workaround: If the compiler is found to not like ebp in assembler, then the above assembly is turned instead into
Code: Select all
__asm__ volatile("pushl %6; xchgl %%ebp, (%%esp); calll *%%gs:16; popl %%ebp" : "+r"(eax) : "r"(ebx), "r"(ecx), "r"(edx), "r"(esi), "r"(edi), "g"(f) : "memory");
I would be somewhat willing to forgive the quirkiness if the compiler was a little bit older. But no, this is with GCC 12, the thing that's currently shipped with Debian.