Why does GCC put a no-op push / pop when using int foo asm ("ebx") to associate var with a register?

I am trying to write code to read from a register, and this is what I still have:

unsigned int readEBX(void) {
    register unsigned int reg asm("ebx");
    return reg;
}

The function works, but it compiles into something strange:

readEBX():
    mov  eax, ebx
    push ebx
    pop  ebx
    ret

Why do this when you use push-then-pop ebx? Doesn't that mean anything? When I replace ebxwith a different register (say eaxor ecx), then it produces cleaner code (just a retand a mov eax, ecx; retrespectively).

See this example result of Godbolt .

+4
source share
3 answers

, , . , , .

( mov)

unsigned int readEBX(void) {
  register unsigned int ret __asm__("eax");
  __asm__ volatile("mov %%ebx, %0" : "=r"(ret));
  return ret;
}

, ret , .

+6

:

- , - .

, , , , gcc push/pop insns /.

asm, ebx - . , , , ebx. readEBX , asm .

+2

push/pop 1

[, reg C, ebx, ebx reg asm], , promises : , ( ) ebx, asm .

, .

/ , ebx , . push .

, ebx, asm,

long reg; asm("mov %%ebx,%0" : "=r"(reg));

, push/pop , , push asm, .


1 .

+2

Source: https://habr.com/ru/post/1611335/


All Articles