Skip to content

Instantly share code, notes, and snippets.

@lancejpollard
Last active April 16, 2024 17:57
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save lancejpollard/adf75b90137ef29e6f02 to your computer and use it in GitHub Desktop.
Save lancejpollard/adf75b90137ef29e6f02 to your computer and use it in GitHub Desktop.
Simple C examples and their Assembly output from GCC 4.9.0

addition

int foo(int a, int b) {
  return a + b;
}
foo(int, int):
  lea eax, [rdi+rsi]
  ret
int foo(int a, int b) {
  return a + b;
}

int main() {
  return foo(3, 4);
}
foo(int, int):
  lea eax, [rdi+rsi]
  ret
main:
  mov eax, 7
  ret

subtraction

int foo(int a, int b) {
  return a - b;
}
foo(int, int):
  mov eax, edi
  sub eax, esi
  ret
int foo(int a, int b) {
  return a - b;
}

int main() {
  return foo(3, 4);
}
foo(int, int):
  mov eax, edi
  sub eax, esi
  ret
main:
  mov eax, -1
  ret

division

int foo(int aa, int bb) {
  return aa / bb;
}
foo(int, int):
  mov eax, edi
  cdq
  idiv  esi
  ret
int foo(int aa, int bb, int cc) {
  return aa / bb / cc;
}
foo(int, int, int):
  mov eax, edi
  mov ecx, edx
  cdq
  idiv  esi
  cdq
  idiv  ecx
  ret
int foo(int aa, int bb, int cc) {
  int sum = aa + bb;
  return sum / cc;
}
foo(int, int, int):
  lea eax, [rdi+rsi]
  mov ecx, edx
  cdq
  idiv  ecx
  ret

multiplication

int foo(int aa, int bb) {
  return aa * bb;
}
foo(int, int):
  mov eax, edi
  imul  eax, esi
  ret
int foo(int aa, int bb, int cc) {
  return aa * bb * cc;
}
foo(int, int, int):
  mov eax, edi
  imul  eax, esi
  imul  eax, edx
  ret
int foo(int aa, int bb, int cc) {
  int sum = aa + bb;
  return sum * cc;
}
foo(int, int, int):
  lea eax, [rdi+rsi]
  imul  eax, edx
  ret

for loop

int foo(int a, int b) {
  int sum = 0;
  for (int i = a; i < b; ++i) {
    sum += i;
  }
  return sum;
}
foo(int, int):
  xor eax, eax
  cmp edi, esi
  jge .L4
.L3:
  add eax, edi
  add edi, 1
  cmp edi, esi
  jne .L3
  rep ret
.L4:
  rep ret
int foo(int rows, int columns) {
  int sum = 0;
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < columns; j++) {
      sum += 1;
    }
  }
  return sum;
}
foo(int, int):
  xor edx, edx
  xor eax, eax
  test  edi, edi
  jle .L3
.L6:
  lea ecx, [rax+rsi]
  test  esi, esi
  cmovg eax, ecx
  add edx, 1
  cmp edx, edi
  jne .L6
.L3:
  rep ret
int bar(int columns) {
  int sum = 0;
  for (int i = 0; i < columns; i++) {
    sum += 1;
  }
  return sum;
}

int foo(int rows, int columns) {
  int sum = 0;
  for (int i = 0; i < rows; i++) {
    sum += bar(columns);
  }
  return sum;
}
bar(int):
  test  edi, edi
  mov eax, 0
  cmovns  eax, edi
  ret
foo(int, int):
  test  edi, edi
  jle .L5
  xor edx, edx
  xor eax, eax
  xor r8d, r8d
.L4:
  test  esi, esi
  mov ecx, r8d
  cmovns  ecx, esi
  add edx, 1
  add eax, ecx
  cmp edx, edi
  jne .L4
  rep ret
.L5:
  xor eax, eax
  ret
int foo(int rows, int columns) {
  int sum = 0;
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < columns; j++) {
      sum += 1;
    }
  }
  return sum;
}

int main() {
 return foo(6, 7);
}
foo(int, int):
  xor edx, edx
  xor eax, eax
  test  edi, edi
  jle .L3
.L6:
  lea ecx, [rax+rsi]
  test  esi, esi
  cmovg eax, ecx
  add edx, 1
  cmp edx, edi
  jne .L6
.L3:
  rep ret
main:
  mov eax, 42
  ret
int foo(int a, int b) {
  int sum = 0;
  for (int i = a; i < b; ++i) {
    sum += i;
  }
  return sum;
}

int main() {
 return foo(6, 7);
}
foo(int, int):
  xor eax, eax
  cmp edi, esi
  jge .L4
.L3:
  add eax, edi
  add edi, 1
  cmp edi, esi
  jne .L3
  rep ret
.L4:
  rep ret
main:
  mov eax, 6
  ret

string utils

from clibs on github

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// bytes

#define KB 1024
#define MB 1024 * KB
#define GB 1024 * MB

/*
 * Convert the given `str` to byte count.
 */

long long
string_to_bytes(const char *str) {
  long long val = strtoll(str, NULL, 10);
  if (!val) return -1;
  if (strstr(str, "kb")) return val * KB;
  if (strstr(str, "mb")) return val * MB;
  if (strstr(str, "gb")) return val * GB;
  return val;
}
.LC0:
  .string "kb"
.LC1:
  .string "mb"
.LC2:
  .string "gb"
string_to_bytes(char const*):
  push  rbp
  push  rbx
  xor esi, esi
  mov edx, 10
  mov rbp, rdi
  sub rsp, 8
  call  strtoll
  test  rax, rax
  mov rbx, rax
  je  .L5
  mov esi, OFFSET FLAT:.LC0
  mov rdi, rbp
  call  strstr
  test  rax, rax
  je  .L3
  mov rax, rbx
  sal rax, 10
.L2:
  add rsp, 8
  pop rbx
  pop rbp
  ret
.L3:
  mov esi, OFFSET FLAT:.LC1
  mov rdi, rbp
  call  strstr
  test  rax, rax
  je  .L4
  mov rax, rbx
  add rsp, 8
  sal rax, 20
  pop rbx
  pop rbp
  ret
.L4:
  mov esi, OFFSET FLAT:.LC2
  mov rdi, rbp
  call  strstr
  mov rdx, rbx
  sal rdx, 30
  test  rax, rax
  mov rax, rbx
  cmovne  rax, rdx
  jmp .L2
.L5:
  mov rax, -1
  jmp .L2

struct

#include <stdio.h>

typedef struct {
  int x;
  int y;
} point;

int main(void) { 
  point p = {1,3};
  printf("x: %d, y: %d", p.x, p.y);
  return 0;
}
.LC0:
  .string "x: %d, y: %d"
main:
  sub rsp, 8
  mov edx, 3
  mov esi, 1
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call  printf
  xor eax, eax
  add rsp, 8
  ret
#include <stdio.h>

typedef struct {
  int x;
  int y;
} point;

int main(void) { 
  point p = {1,3};
  point q;
  q = p;
  q.x = 3;
  if (p.x != q.x) printf("The members are not equal! %d != %d", p.x, q.x);
  return 0;
}
.LC0:
  .string "The members are not equal! %d != %d"
main:
  sub rsp, 8
  mov edx, 3
  mov esi, 1
  mov edi, OFFSET FLAT:.LC0
  xor eax, eax
  call  printf
  xor eax, eax
  add rsp, 8
  ret
@worthless443
Copy link

lot of fun, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment