Skip to content

Instantly share code, notes, and snippets.

@seisvelas
Last active December 10, 2018 20:13
Show Gist options
  • Save seisvelas/a09fb1650a6bffbd7dc8393edf9462f5 to your computer and use it in GitHub Desktop.
Save seisvelas/a09fb1650a6bffbd7dc8393edf9462f5 to your computer and use it in GitHub Desktop.
Learnin' C
#include <stdlib.h>
int main(void) {
int edi = 5; // nth fib num
int ebx = 0;
int eax = 1;
int edx; // tmp
start_loop:
--edi;
if (edi==0) { goto loop_exit; }
edx = eax;
eax += ebx;
ebx = edx;
goto start_loop;
loop_exit:
return ebx;
}
.section .data
.section .text
.globl _start
_start:
movl $10, %edi # number of fibnum we hunt
movl $0, %ebx # 1st fibnum
movl $1, %eax # 2nd fibnum
arb_label:
## Check if %edi is 0
## (thus meaning %ebx is nth fibnum)
## and if so, exit loop
decl %edi
cmpl $0, %edi
je loop_exit
## core Fibonnaci algorithm
## (hold %eax in tmp register %edx,
## eax = eax + ebx,
## ebx = edx)
movl %eax, %edx
addl %ebx, %eax
movl %edx, %ebx
jmp arb_label
## Once loop completes...
loop_exit:
movl $1, %eax
int $0x80
@informatimago
Copy link

$ cat fib.c
#include <stdio.h>

int nth_fib(int n){
    int fib_n_2=0;
    int fib_n_1=1;
    while(0<n--){
        int temp=fib_n_2;
        fib_n_2=fib_n_1;
        fib_n_1+=temp;}
    return fib_n_2;}

int main(){
    int n=5;
    /* See: https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html */
    printf("%dth fib is %d\n",n,nth_fib(n-1));
    return 0;}

$ gcc -O3 -S -o fib.s fib.c && cat fib.s

	.section	__TEXT,__text,regular,pure_instructions
	.build_version macos, 10, 14
	.globl	_nth_fib                ## -- Begin function nth_fib
	.p2align	4, 0x90
_nth_fib:                               ## @nth_fib
	.cfi_startproc
## %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	testl	%edi, %edi
	jle	LBB0_1
## %bb.2:
	incl	%edi
	xorl	%ecx, %ecx
	movl	$1, %edx
	.p2align	4, 0x90
LBB0_3:                                 ## =>This Inner Loop Header: Depth=1
	movl	%edx, %eax
	addl	%eax, %ecx
	decl	%edi
	movl	%ecx, %edx
	movl	%eax, %ecx
	cmpl	$1, %edi
	jg	LBB0_3
## %bb.4:
	popq	%rbp
	retq
LBB0_1:
	xorl	%eax, %eax
	popq	%rbp
	retq
	.cfi_endproc
                                        ## -- End function
	.globl	_main                   ## -- Begin function main
	.p2align	4, 0x90
_main:                                  ## @main
	.cfi_startproc
## %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register %rbp
	leaq	L_.str(%rip), %rdi
	movl	$5, %esi
	movl	$3, %edx
	xorl	%eax, %eax
	callq	_printf
	xorl	%eax, %eax
	popq	%rbp
	retq
	.cfi_endproc
                                        ## -- End function
	.section	__TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
	.asciz	"%dth fib is %d\n"


.subsections_via_symbols

@seisvelas
Copy link
Author

seisvelas commented Nov 30, 2018

@informatimago

My handwritten assembly code written without optimization in mind outperforms GCC's assembly compilation of your code in terms of speed.I am using the Linux time command. How strange. I don't know why.

edit: Well, I have an idea of why (your program makes use of a pricey function call that gives my function-less version a slight edge). But what I mean to say is, I don't know why GCC at -O3 can't optimize away the function call entirely.

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