Skip to content

Instantly share code, notes, and snippets.

@dcalacci
Created September 19, 2012 03:35

Revisions

  1. Dan Calacci revised this gist Sep 19, 2012. 1 changed file with 67 additions and 67 deletions.
    134 changes: 67 additions & 67 deletions factorial.asm
    Original file line number Diff line number Diff line change
    @@ -1,112 +1,112 @@
    .globl main
    .data
    msgprompt: .word msgprompt_data
    msgres1: .word msgres1_data
    msgres2: .word msgres2_data
    msgprompt: .word msgprompt_data
    msgres1: .word msgres1_data
    msgres2: .word msgres2_data

    msgprompt_data: .asciiz "Positive integer: "
    msgres1_data: .asciiz "The value of factorial("
    msgres2_data: .asciiz ") is "
    msgprompt_data: .asciiz "Positive integer: "
    msgres1_data: .asciiz "The value of factorial("
    msgres2_data: .asciiz ") is "

    # every function call has a stack segment of 12 bytes, or 3 words.
    # the space is reserved as follows:
    # 0($sp) is reserved for the initial value given to this call
    # 4($sp) is the space reserved for a return value
    # 8($sp) is the space reserved for the return address.
    # 0($sp) is reserved for the initial value given to this call
    # 4($sp) is the space reserved for a return value
    # 8($sp) is the space reserved for the return address.
    # calls may manipulate their parent's data, but parents may not
    # manipulate their child's data.
    # i.e: if we have a call A who has a child call B:
    # B may run:
    # sw $t0, 16($sp)
    # which would store data from $t0 into the parent's return value register
    # A, however, should not(and, in all cases I can think of, cannot) manipulate
    # any data that belongs to a child call.
    # B may run:
    # sw $t0, 16($sp)
    # which would store data from $t0 into the parent's return value register
    # A, however, should not(and, in all cases I can think of, cannot) manipulate
    # any data that belongs to a child call.


    .text
    main:
    # printing the prompt
    # printing the prompt
    #printf("Positive integer: ");
    la $t0, msgprompt # load address of msgprompt into $t0
    lw $a0, 0($t0) # load data from address in $t0 into $a0
    li $v0, 4 # call code for print_string
    syscall # run the print_string syscall
    la $t0, msgprompt # load address of msgprompt into $t0
    lw $a0, 0($t0) # load data from address in $t0 into $a0
    li $v0, 4 # call code for print_string
    syscall # run the print_string syscall

    # reading the input int
    # reading the input int
    # scanf("%d", &number);
    li $v0, 5 # call code for read_int
    syscall # run the read_int syscall
    move $t0, $v0 # store input in $t0
    li $v0, 5 # call code for read_int
    syscall # run the read_int syscall
    move $t0, $v0 # store input in $t0

    move $a0, $t0 # move input to argument register $a0
    addi $sp, $sp, -12 # move stackpointer up 3 words
    sw $t0, 0($sp) # store input in top of stack
    sw $ra, 8($sp) # store counter at bottom of stack
    jal factorial # call factorial
    move $a0, $t0 # move input to argument register $a0
    addi $sp, $sp, -12 # move stackpointer up 3 words
    sw $t0, 0($sp) # store input in top of stack
    sw $ra, 8($sp) # store counter at bottom of stack
    jal factorial # call factorial

    # when we get here, we have the final return value in 4($sp)
    # when we get here, we have the final return value in 4($sp)

    lw $s0, 4($sp) # load final return val into $s0
    lw $s0, 4($sp) # load final return val into $s0

    # printf("The value of 'factorial(%d)' is: %d\n",
    la $t1, msgres1 # load msgres1 address into $t1
    lw $a0, 0($t1) # load msgres1_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres1_data to screen
    la $t1, msgres1 # load msgres1 address into $t1
    lw $a0, 0($t1) # load msgres1_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres1_data to screen

    lw $a0, 0($sp) # load original value into $a0
    li $v0, 1 # system call for print_int
    syscall # print original value to screen
    lw $a0, 0($sp) # load original value into $a0
    li $v0, 1 # system call for print_int
    syscall # print original value to screen

    la $t2, msgres2 #load msgres2 address into $t1
    lw $a0, 0($t2) # load msgres_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres2_data to screen
    la $t2, msgres2 #load msgres2 address into $t1
    lw $a0, 0($t2) # load msgres_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres2_data to screen

    move $a0, $s0 # move final return value from $s0 to $a0 for return
    li $v0, 1 # system call for print_int
    syscall # print final return value to screen
    move $a0, $s0 # move final return value from $s0 to $a0 for return
    li $v0, 1 # system call for print_int
    syscall # print final return value to screen

    addi $sp, $sp, 12 # move stack pointer back down where we started
    addi $sp, $sp, 12 # move stack pointer back down where we started

    # return 0;
    li $v0, 10 # system call for exit
    syscall # exit!
    li $v0, 10 # system call for exit
    syscall # exit!



    .text
    factorial:
    # base case - still in parent's stack segment
    lw $t0, 0($sp) # load input from top of stack into register $t0
    # base case - still in parent's stack segment
    lw $t0, 0($sp) # load input from top of stack into register $t0
    #if (x == 0)
    beq $t0, 0, returnOne # if $t0 is equal to 0, branch to returnOne
    addi $t0, $t0, -1 # subtract 1 from $t0 if not equal to 0
    beq $t0, 0, returnOne # if $t0 is equal to 0, branch to returnOne
    addi $t0, $t0, -1 # subtract 1 from $t0 if not equal to 0

    # recursive case - move to this call's stack segment
    addi $sp, $sp, -12 # move stack pointer up 3 words
    sw $t0, 0($sp) # store current working number into the top of the stack segment
    sw $ra, 8($sp) # store counter at bottom of stack segment
    # recursive case - move to this call's stack segment
    addi $sp, $sp, -12 # move stack pointer up 3 words
    sw $t0, 0($sp) # store current working number into the top of the stack segment
    sw $ra, 8($sp) # store counter at bottom of stack segment

    jal factorial # recursive call
    jal factorial # recursive call

    # if we get here, then we have the child return value in 4($sp)
    lw $ra, 8($sp) # load this call's $ra again(we just got back from a jump)
    lw $t1, 4($sp) # load child's return value into $t1
    # if we get here, then we have the child return value in 4($sp)
    lw $ra, 8($sp) # load this call's $ra again(we just got back from a jump)
    lw $t1, 4($sp) # load child's return value into $t1

    lw $t2, 12($sp) # load parent's start value into $t2
    lw $t2, 12($sp) # load parent's start value into $t2
    # return x * factorial(x-1); (not the return statement, but the multiplication)
    mul $t3, $t1, $t2 # multiply child's return value by parent's working value, store in $t3.
    mul $t3, $t1, $t2 # multiply child's return value by parent's working value, store in $t3.

    sw $t3, 16($sp) # take result(in $t3), store in parent's return value.
    sw $t3, 16($sp) # take result(in $t3), store in parent's return value.

    addi $sp, $sp, 12 # move stackpointer back down for the parent call
    addi $sp, $sp, 12 # move stackpointer back down for the parent call

    jr $ra # jump to parent call
    jr $ra # jump to parent call

    .text
    #return 1;
    returnOne:
    li $t0, 1 # load 1 into register $t0
    sw $t0, 4($sp) # store 1 into the parent's return value register
    jr $ra # jump to parent call
    li $t0, 1 # load 1 into register $t0
    sw $t0, 4($sp) # store 1 into the parent's return value register
    jr $ra # jump to parent call
  2. Dan Calacci revised this gist Sep 19, 2012. 1 changed file with 21 additions and 21 deletions.
    42 changes: 21 additions & 21 deletions factorial.asm
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    msgprompt: .word msgprompt_data
    msgres1: .word msgres1_data
    msgres2: .word msgres2_data

    msgprompt_data: .asciiz "Positive integer: "
    msgres1_data: .asciiz "The value of factorial("
    msgres2_data: .asciiz ") is "
    @@ -19,7 +19,7 @@
    # B may run:
    # sw $t0, 16($sp)
    # which would store data from $t0 into the parent's return value register
    # A, however, should not(and, in all cases I can think of, cannot) manipulate
    # A, however, should not(and, in all cases I can think of, cannot) manipulate
    # any data that belongs to a child call.


    @@ -31,49 +31,49 @@ main:
    lw $a0, 0($t0) # load data from address in $t0 into $a0
    li $v0, 4 # call code for print_string
    syscall # run the print_string syscall

    # reading the input int
    # scanf("%d", &number);
    # scanf("%d", &number);
    li $v0, 5 # call code for read_int
    syscall # run the read_int syscall
    move $t0, $v0 # store input in $t0

    move $a0, $t0 # move input to argument register $a0
    addi $sp, $sp, -12 # move stackpointer up 3 words
    sw $t0, 0($sp) # store input in top of stack
    sw $ra, 8($sp) # store counter at bottom of stack
    jal factorial # call factorial

    # when we get here, we have the final return value in 4($sp)

    lw $s0, 4($sp) # load final return val into $s0

    # printf("The value of 'factorial(%d)' is: %d\n",
    la $t1, msgres1 # load msgres1 address into $t1
    lw $a0, 0($t1) # load msgres1_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres1_data to screen

    lw $a0, 0($sp) # load original value into $a0
    li $v0, 1 # system call for print_int
    syscall # print original value to screen

    la $t2, msgres2 #load msgres2 address into $t1
    lw $a0, 0($t2) # load msgres_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres2_data to screen

    move $a0, $s0 # move final return value from $s0 to $a0 for return
    li $v0, 1 # system call for print_int
    syscall # print final return value to screen

    addi $sp, $sp, 12 # move stack pointer back down where we started

    # return 0;
    li $v0, 10 # system call for exit
    syscall # exit!



    .text
    factorial:
    @@ -87,21 +87,21 @@ factorial:
    addi $sp, $sp, -12 # move stack pointer up 3 words
    sw $t0, 0($sp) # store current working number into the top of the stack segment
    sw $ra, 8($sp) # store counter at bottom of stack segment

    jal factorial # recursive call

    # if we get here, then we have the child return value in 4($sp)
    lw $ra, 8($sp) # load this call's $ra again(we just got back from a jump)
    lw $t1, 4($sp) # load child's return value into $t1

    lw $t2, 12($sp) # load parent's start value into $t2
    # return x * factorial(x-1); (not the return statement, but the multiplication)
    mul $t3, $t1, $t2 # multiply child's return value by parent's working value, store in $t3.

    sw $t3, 16($sp) # take result(in $t3), store in parent's return value.

    addi $sp, $sp, 12 # move stackpointer back down for the parent call

    jr $ra # jump to parent call

    .text
  3. Dan Calacci created this gist Sep 19, 2012.
    112 changes: 112 additions & 0 deletions factorial.asm
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    .globl main
    .data
    msgprompt: .word msgprompt_data
    msgres1: .word msgres1_data
    msgres2: .word msgres2_data
    msgprompt_data: .asciiz "Positive integer: "
    msgres1_data: .asciiz "The value of factorial("
    msgres2_data: .asciiz ") is "

    # every function call has a stack segment of 12 bytes, or 3 words.
    # the space is reserved as follows:
    # 0($sp) is reserved for the initial value given to this call
    # 4($sp) is the space reserved for a return value
    # 8($sp) is the space reserved for the return address.
    # calls may manipulate their parent's data, but parents may not
    # manipulate their child's data.
    # i.e: if we have a call A who has a child call B:
    # B may run:
    # sw $t0, 16($sp)
    # which would store data from $t0 into the parent's return value register
    # A, however, should not(and, in all cases I can think of, cannot) manipulate
    # any data that belongs to a child call.


    .text
    main:
    # printing the prompt
    #printf("Positive integer: ");
    la $t0, msgprompt # load address of msgprompt into $t0
    lw $a0, 0($t0) # load data from address in $t0 into $a0
    li $v0, 4 # call code for print_string
    syscall # run the print_string syscall
    # reading the input int
    # scanf("%d", &number);
    li $v0, 5 # call code for read_int
    syscall # run the read_int syscall
    move $t0, $v0 # store input in $t0
    move $a0, $t0 # move input to argument register $a0
    addi $sp, $sp, -12 # move stackpointer up 3 words
    sw $t0, 0($sp) # store input in top of stack
    sw $ra, 8($sp) # store counter at bottom of stack
    jal factorial # call factorial
    # when we get here, we have the final return value in 4($sp)
    lw $s0, 4($sp) # load final return val into $s0
    # printf("The value of 'factorial(%d)' is: %d\n",
    la $t1, msgres1 # load msgres1 address into $t1
    lw $a0, 0($t1) # load msgres1_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres1_data to screen
    lw $a0, 0($sp) # load original value into $a0
    li $v0, 1 # system call for print_int
    syscall # print original value to screen
    la $t2, msgres2 #load msgres2 address into $t1
    lw $a0, 0($t2) # load msgres_data value into $a0
    li $v0, 4 # system call for print_string
    syscall # print value of msgres2_data to screen
    move $a0, $s0 # move final return value from $s0 to $a0 for return
    li $v0, 1 # system call for print_int
    syscall # print final return value to screen
    addi $sp, $sp, 12 # move stack pointer back down where we started
    # return 0;
    li $v0, 10 # system call for exit
    syscall # exit!

    .text
    factorial:
    # base case - still in parent's stack segment
    lw $t0, 0($sp) # load input from top of stack into register $t0
    #if (x == 0)
    beq $t0, 0, returnOne # if $t0 is equal to 0, branch to returnOne
    addi $t0, $t0, -1 # subtract 1 from $t0 if not equal to 0

    # recursive case - move to this call's stack segment
    addi $sp, $sp, -12 # move stack pointer up 3 words
    sw $t0, 0($sp) # store current working number into the top of the stack segment
    sw $ra, 8($sp) # store counter at bottom of stack segment
    jal factorial # recursive call
    # if we get here, then we have the child return value in 4($sp)
    lw $ra, 8($sp) # load this call's $ra again(we just got back from a jump)
    lw $t1, 4($sp) # load child's return value into $t1
    lw $t2, 12($sp) # load parent's start value into $t2
    # return x * factorial(x-1); (not the return statement, but the multiplication)
    mul $t3, $t1, $t2 # multiply child's return value by parent's working value, store in $t3.
    sw $t3, 16($sp) # take result(in $t3), store in parent's return value.
    addi $sp, $sp, 12 # move stackpointer back down for the parent call
    jr $ra # jump to parent call

    .text
    #return 1;
    returnOne:
    li $t0, 1 # load 1 into register $t0
    sw $t0, 4($sp) # store 1 into the parent's return value register
    jr $ra # jump to parent call