Skip to content

Instantly share code, notes, and snippets.

@cetfor
Last active November 8, 2021 12:27
Show Gist options
  • Save cetfor/d9e864860c46748af52bb352f2aa2e5f to your computer and use it in GitHub Desktop.
Save cetfor/d9e864860c46748af52bb352f2aa2e5f to your computer and use it in GitHub Desktop.
Example source for my calling conventions article
// gcc -m32 -mpreferred-stack-boundary=2 cdecl.c -o cdecl
#include <stdio.h>
void printFavNums(int num1, int num2) {
printf("My favorite numbers are %d and %d!\n", num1, num2);
}
int main()
{
printFavNums(2, 8);
return 0;
}
// gcc -m32 -mpreferred-stack-boundary=2 fastcall.c -o fastcall
#include <stdio.h>
__attribute__((fastcall)) void printFavNums(int num1, int num2, int num3) {
printf("My favorite numbers are %d, %d and %d!\n", num1, num2, num3);
}
int main()
{
printFavNums(2, 8, 22);
return 0;
}
// gcc -m32 -mpreferred-stack-boundary=2 noway.c -o yesway
#include <stdio.h>
__attribute__((thiscall)) void printFavNums(int favNum1, int favNum2) {
printf("My favorite numbers are %d and %d!\n", favNum1, favNum2);
}
int main()
{
printFavNums(2, 8);
return 0;
}
// gcc -m32 -mpreferred-stack-boundary=2 stdcall.c -o stdcall
#include <stdio.h>
__attribute__((stdcall)) void printFavNums(int num1, int num2) {
printf("My favorite numbers are %d and %d!\n", num1, num2);
}
int main()
{
printFavNums(2, 8);
return 0;
}
// gcc systemv.c -o systemv
#include <stdio.h>
#include <stdint.h>
void printFavNums(uint64_t n1, uint64_t n2, uint64_t n3,
uint64_t n4, uint64_t n5, uint64_t n6) {
printf("My favorite numbers are %lld, %lld, %lld, %lld, %lld, and %lld!\n",
n1, n2, n3, n4, n5, n6);
}
int main()
{
uint64_t a, b, c, d, e, f = 0;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
f = 6;
printFavNums(a,b,c,d,e,f);
return 0;
}
// g++ -m32 -mpreferred-stack-boundary=2 thiscall.cpp -o thiscall
#include <iostream>
#include "bits/c++config.h"
using namespace std;
class FavoriteNumbers {
public:
int num1, num2;
//__attribute__((thiscall))
void printFavNums(int number1, int number2) {
std::cout << "My favorite numbers are " << number1
<< " and " << number2 << endl;
}
};
int main()
{
FavoriteNumbers *favNums = new FavoriteNumbers();
favNums->num1 = 2;
favNums->num2 = 8;
favNums->printFavNums(favNums->num1, favNums->num2);
return 0;
}
// gcc -m32 -mpreferred-stack-boundary=2 variadic.c -o variadic
#include <stdio.h>
#include <stdarg.h>
//__attribute__((stdcall))
void printFavNums(char *format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
int main()
{
printFavNums("My favorite numbers are: %d, %d, and %d!\n", 2, 8, 22);
return 0;
}
#include "stdafx.h"
#include <stdio.h>
#include <stdint.h>
void printFavNums(uint64_t n1, uint64_t n2, uint64_t n3,
uint64_t n4, uint64_t n5, uint64_t n6) {
printf("My favorite numbers are %lld, %lld, %lld, %lld, %lld, and %lld!\n",
n1, n2, n3, n4, n5, n6);
}
int main()
{
uint64_t a, b, c, d, e, f = 0;
a = 1;
b = 2;
c = 3;
d = 4;
e = 5;
f = 6;
printFavNums(a,b,c,d,e,f);
return 0;
}
Convention Stack cleanup Parameter passing
Microsoft x64 Caller First four arguments in RCX RDX R8 R9 the rest on stack in reverse order
System-V Caller First six arguments in RDI RSI RDX RCX R8 R9 the rest on the stack in reverse order
Convention Stack cleanup Parameter passing
cdecl Caller Pushes parameters on the stack in reverse order (right to left)
fastcall Callee First two in registers the rest on the stack in reverse order
stdcall Callee Pushes parameters on the stack in reverse order
thiscall Callee First param in ECX (usually this) the rest on the stack in reverse order
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment