0

As you might have guessed the question is does gcc automaticly saves callee-save registers or should I do it by myself? I thought that gcc would do that for me but when I wrote this code

void foo(void) {
    __asm__ volatile ("mov $123, %rbx");
}

void main(void) {
    foo();
}

after gcc a.c && objdump -d a.out I saw this

00000000004004f6 <foo>:
  4004f6:   55                      push   %rbp
  4004f7:   48 89 e5                mov    %rsp,%rbp
  4004fa:   48 c7 c3 7b 00 00 00    mov    $0x7b,%rbx
  400501:   90                      nop
  400502:   5d                      pop    %rbp
  400503:   c3                      retq   

0000000000400504 <main>:
  400504:   55                      push   %rbp
  400505:   48 89 e5                mov    %rsp,%rbp
  400508:   e8 e9 ff ff ff          callq  4004f6 <foo>
  40050d:   90                      nop
  40050e:   5d                      pop    %rbp
  40050f:   c3                      retq

According to x86-64 ABI %rbx is a callee-save register but in this code gcc did not save it in foo before modifying. Is it just because I don't use %rbx in main function after calling foo() or it's bacause gcc does not provide such garanties and I have to save it by myself in foo before modifying?

PepeHands
  • 1,368
  • 5
  • 20
  • 36
  • 2
    GCC doesn't pay attention to your inline asm, it just emits it verbatim. It's up to you to do the right thing. – Oliver Charlesworth Mar 31 '16 at 20:25
  • 1
    It would be pretty boggy code that saves and restores every register by rote. – Weather Vane Mar 31 '16 at 20:26
  • @WeatherVane so does it means that `gcc` wont preseve this registers and I should save them by myself? – PepeHands Mar 31 '16 at 20:31
  • 1
    As @OliverCharlesworth wrote. You are on your own here, gcc has no idea what your intentions are. – Weather Vane Mar 31 '16 at 20:33
  • @WeatherVane then I don't understand when `gcc` would save this registers and when it would not. – PepeHands Mar 31 '16 at 20:35
  • 1
    It would save registers affected by the C code it has compiled. The assembler allows you to get under the hood, but it won't replace the spark plugs for you. – Weather Vane Mar 31 '16 at 20:36
  • 1
    You can use [extended inline assembly](https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html) and tell the compiler what registers you clobber, then it will save them. – Some programmer dude Mar 31 '16 at 20:51
  • @WeatherVane thanks, I think I got it. Could you write this as an answer so I could accept it? – PepeHands Mar 31 '16 at 20:53
  • @OliverCharlesworth thanks. I think after some explanations from WeatherVane I got it) – PepeHands Mar 31 '16 at 20:54
  • 1
    See [the end of this answer](http://stackoverflow.com/questions/34520013/using-base-pointer-register-in-c-inline-asm/34522750#34522750) for a list of guides and resources about GNU C inline asm. The first part of that answer explains my GNU inline asm is not a good way to learn asm. (see also the [x86 tag wiki](http://stackoverflow.com/tags/x86/info) – Peter Cordes Mar 31 '16 at 20:58
  • @Dima thanks but there is a better answer. – Weather Vane Mar 31 '16 at 21:03

2 Answers2

3

Gcc will automatically save and restore all callee-save registers THAT IT KNOWS ARE USED. It knows about registers it uses itself, but it will only know about registers used in inline assembly if you tell it. That's what the 'clobbers' list is for:

void foo(void) {
    __asm__ volatile ("mov $123, %%rbx" : : : "rbx");
}

Now the compiler knows that you are using/modifying rbx, so it will save it if it needs to.

Note that you really want to do it this way rather than trying to save it yourself, as this way it will only be saved once if gcc also wants to use the register for something in this function.

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • The `asm` keyword is prefered over `__asm__` unless you're writing library code that needs to work even if the user does something like `#define asm 1`. Oh, but the OP used `__asm__`, so you're just following that. – Peter Cordes Mar 31 '16 at 21:01
1

It would be pretty boggy code that saves and restores every register by rote. The compiler saves registers within the C code it has compiled, but you are on your own here, gcc has no idea what your intentions are.

The assembler allows you to get under the hood, but it won't replace the spark plugs for you.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56