<div dir="ltr">Hello.<br>I'm trying to understand how fastcall works.<br><br>As far as I know, first two integer type arguments are passed in ecx and edx.<br>I tested several test, but the result was different from what I expected<br><br>#1<br>    typedef struct _data_t {<br>        int d;<br>    } data_t;<br><br>    void __attribute__((fastcall)) test_suuu(data_t s, unsigned int a, unsigned int b, unsigned int c);<br> <br>unsigned int a is passed in edx, and the rest are passed in stack (in s, b, c order).<br><br>#2 : order of arguments is diff from #1<br>   void __attribute__((fastcall)) test_usuu(unsigned int a, data_t s, unsigned int b, unsigned int c);<br><br>unsigned int a is passed in ecx, and the rest are passed in stack (in s, b, c order)<br><br>#3 : __attribute__((__packed__)) is diff from #1<br>    typedef struct __attribute__((__packed__)) _data_t3 {<br>        int d;<br>    } data_t3;<br>   <br>    void __attribute__((fastcall)) test_s3uu(data_t3 s3, unsigned int a, unsigned int b);<br><br>unsigned int a is passed in ecx, and the rest are passed in stack (in s, b, c order)<br><br><div>My questions are as follow  <br>- why struct s in first test is passed in edx not ecx?<br>- why unsigned b is in second test is passed in stack not edx?</div><div>- why 'packed' makes a difference?<br>- where can I find relevant code in llvm?<br><br>I'm using i586, linux, llvm 5.02<br>Build with "clang++ -std=c++11 -ggdb -O0 -gdwarf-4 -fno-omit-frame-pointer -fno-optimize-sibling-calls -o ref_test ref_test.cpp"</div><div>(All arguments are used in the function so that they are not optimized out)<br>Tested with gdb<br>    (gdb) break* test_suuu<br>    (gdb) x/6wx $esp<br>    (gdb) i r<br></div></div>