The following is my implementation of the absolute value function in the MIPS assembly language. I would very much like to hear constructive criticism of my code from you as well as any words of wisdom you want to pass my way. The code is heavily commented.
################################################################################
# #
# File name: abs.a #
# #
# This program prints on the console the absolute value of the number declared #
# in the data section. #
# #
################################################################################
################################
# #
# System call code constants #
# #
################################
SYS_PRINT_INT = 0x01
SYS_PRINT_STRING = 0x04
SYS_EXIT = 0x0A
.globl __start
.data
x: .word 0xFFFFFFFC # 0xFFFFFFFC = -4
endl: .asciiz "\n"
.text
__start: lw $a0, x # Load $a0 with the value of x
jal _abs # Call the abs subroutine
add $t0, $v0, $zero # Move the result into $t0
li $v0, SYS_PRINT_INT # Print the result
move $a0, $t0
syscall
li $v0, SYS_PRINT_STRING # Print a newline
la $a0, endl
syscall
li $v0, SYS_EXIT # Exit the program
syscall
################################################################################
# #
# The abs function takes a 32-bit singed two's compliment number as an #
# argument and returns its absolute value. #
# #
# $a0 - the number to find the absolute value of #
# $v0 - the result of the function #
# #
# #
# Implementation details: #
# #
# If the number is negative, we need to negate it to get its absolute value. #
# If it's positive, we don't have to do anything. We just return the number #
# itself. To find out whether a number is negative or positive, we need to #
# examine its most significant bit. If it's got a zero in there, the number is #
# positive. If it's instead got a one in there, and since we're using a singed #
# two's compliment binary representation, the number is negative. So, we shift #
# the number 16 positions to the left and save the result in the $t0 register. #
# Then, we use a bit mask of 0x8000 (1000 0000 0000 0000 in binary) to extract #
# the most significant bit. And lastly, we use the branch on equal to zero #
# operation to either save the number in the $v0 register and return from the #
# function if the number is positive or negate it if it's negative. To negate #
# it, we use the nor oration and add one to it. #
# #
################################################################################
_abs: srl $t0, $a0, 16 # Shit 16 positions to the right
andi $t0, $t0, 0x8000 # Extract the most significant bit
beqz $t0, skip # If it's zero, jump to "skip"
nor $a0, $a0, $zero # If it doesn't equal to zero,
addi $a0, 1 # make it positive
skip: add $v0, $a0, $zero # Move the result into $v0
jr $ra # Return to the call site
################################################################################
# #
# end of function #
# #
################################################################################
Test:
$ spim -notrap file abs.a
$ 4