1

Suppose we are given a simple program

#include <cstdio>

int main(int argc, char* argv[]) {
    int n = argc;
    if (n > 1) {
        n = 1;
    }else {
        n = -1;
    }
    printf("%d\n", n);
    return 0;
}

and assembly code snippet generated using g++ main.cpp -S -O1 under ubuntu x64(Windows subsystem)

subq    $8, %rsp
cmpl    $1, %edi
setg    %dl
movzbl  %dl, %edx
leal    -1(%rdx,%rdx), %edx
movl    $.LC0, %esi
movl    $1, %edi
movl    $0, %eax
call    __printf_chk
movl    $0, %eax
addq    $8, %rsp
ret

There is neither a push nor any instruction that accesses and writes memory. So the argument n must be passed through %edx. Now I wonder how the c library function __printf_chk knows that %edx contains the expected argument? More generally, how does it know which register(s) has(have) used?

kayochin
  • 431
  • 6
  • 11
  • Possible duplicate of [What is an application binary interface (ABI)?](https://stackoverflow.com/q/2171177/608639), [Register allocation rules in code generated by major C/C++ compilers](https://stackoverflow.com/q/256220/608639), [What are the different calling conventions in C/C++ and what do each mean?](https://stackoverflow.com/q/949862/608639), etc. – jww Apr 15 '18 at 19:30

1 Answers1

5

This is specified by the platform's ABI (application binary interface). The compiler has compiled __printf_chk to follow your platforms ABI (in this case, the amd64 SysV ABI), causing it to expect arguments to be in certain locations. For further reading, have a look at this ABI document.

fuz
  • 88,405
  • 25
  • 200
  • 352