The irresistable source.

lab 4

1. Description

This program is a calculator similar to lab2 except that it is written in C instead of HLA. The purpose of rewriting the program was so that we could compile it with the -S switch to take a look at the assembly code generated.

Upon examining the assembly code, the most salient observation was the compilers use of labels. When humans write assembly code, we (hopefully) use labels with names that make sense for what they are accomplishing, such as “menu:”, “Add:”, etc. However, when the compiler generates assembly code, the names it uses for labels are less readable but not completely devoid of information. Labels that begin with “LF” appear to denote information about functions. There appear to be two types of function labels; labels that start with “LFB” are the beginning of the function before the user code starts and labels that start with “LFE” are the end of functions that follow the user code.

All of the string literals used in the program get their own labels and begin with “LC” followed by a number. Labels for user generated code just begin with “L” and are followed by a number.

The compiler’s handling of if statements are sometimes unusual; the long if-else chain in the ToRoman function was altered so that the left values being compared were one less than the value from the C source. For example instead of comparing if num was greater than or equal to 1000, it would instead check to see if 999 was less than or equal to num. Jumping on the opposite condition in assembly was expected, however it’s not immediately clear why the compiler decrements first and jumps if less than or equal instead of comparing 1000 to num and jumping if less than.

2. Code

//Program to implement a Calculator in C
//Author: Jason Warren
//Date: 11/11/13

#include

int GetOperand(void);
int Mult(int, int);
int Exp(int, int);
void ToRoman(int);

int main(){

	int menu_selection;
	int left_operand;
	int right_operand;
	int result;

	do{
        printf("Enter your operation:n");
        printf("1 - Convert to Roman numeralsn");
        printf("2 - Additionn");
        printf("3 - Subtractionn");
        printf("4 - Multiplicationn");
        printf("5 - Exponentiationn");
        printf("9 - Exitn");
        printf("> ");
        scanf("%d", &menu_selection);

        //If command was '1' - Convert to Roman
        if(menu_selection == 1){
            printf("Enter number to covert to Roman: ");
            scanf("%d", &left_operand );	//Store user input in eax
            ToRoman(left_operand);
            printf("n");
        }
        //Endif Convert to Roman

        //If command was '2' or '3' - Add/Sub
        else if(menu_selection == 2 || menu_selection == 3){

            left_operand = GetOperand();
            right_operand = GetOperand();
            printf("%d", left_operand);
            if(menu_selection == 2){
                printf("+");
            }
            else{
                printf("-");
            }
            printf("%d", right_operand);
            printf("=");
            if(menu_selection == 2){
                result = left_operand + right_operand;
            }
            else{
                result = left_operand - right_operand;
            }
            printf("%dn", result);
        }
        //endif Add/Sub

        //If multiply command
        else if(menu_selection == 4){
            left_operand = GetOperand();
            right_operand = GetOperand();
            printf("%d*%d=",left_operand, right_operand);
            result = Mult(left_operand, right_operand);
            printf("%d", result);
            printf("n");
        }
        //Endif multiply

        //If Exp command
        else if(menu_selection == 5){
            left_operand = GetOperand();
            right_operand = GetOperand();
            printf("%d^%d=",left_operand, right_operand);
            result = Exp(left_operand, right_operand);
            printf("%un",result);
        }
        //Endif Exp

        //If Exit command.
        else{
            printf("Goodbye.n");
        }
    }while(menu_selection >= 1 && menu_selection <= 5); 	return 0; } //Module:GetOperands //Description: Gets operand from user and ensures that the value can be represented with 16bits. //Parameters: //Returns: operand int GetOperand(void){ 	int operand; 	printf("Enter the left operand: "); 	scanf("%d", &operand);	//Temporarily Store left operand in eax 	while(operand >= 65536){
		printf("Operand must be < 65536: ");
		scanf("%d", &operand);
	}
	return operand;
}
//End GetOperands

//Module:Mult
//Description: Multiplies two numbers.
//Parameters: ebx - left operand, eax - right operand
//Modifies: eax
//Returns: eax - value of multiplication
int Mult(int left_operand, int right_operand){
	int result = 0;
	int i;

	if(left_operand <= right_operand){
		for(i=0; i<left_operand; i++){
			//add(eax,edx);
			result = right_operand + result;
		}
	}
	else{
		for(i=0; i<right_operand; i++){
			//add(ebx,edx);
			result = left_operand + result;
		}
	}
	return result;
}
//End Mult

//Module:Exp
//Description: Raises a number in ebx to the power of eax
//Paramenters: ebx - base number, eax - exponent
//Modifies: eax, ecx, edx
//Returns: eax - result
int Exp(int base, int exponent){

	int result;

	if(exponent != 0){
		result = base;
		int i;
		for(i=1; i<exponent; i++){ 			result = Mult(result, base); 		} 	} 	else{ 		result = 1; 	} 	return result; } //End Exp //Module:ToRoman //Displays a Roman numeral representation of the value in eax. //Parameters: //eax - Number to convert to Roman numerals. //Modifies: eax void ToRoman(int num){ 	while( num > 0 ){
		if(num >= 1000){
			printf("M");
			num = num - 1000;
		}

		//if result is between 500(inclusive) and 1k(exclusive)
		else if(num >= 500){
			if(num >= 900){
				printf("CM");
				num = num - 900;
			}
			else{
				printf("D");
				num = num - 500;
			}
		}

		//if result is between 100(inc) and 500(exclusive)
		else if(num >= 100){
			if(num >= 400){
				printf("CD");
				num = num - 400;
			}
			else{
				printf("C");
				num = num - 100;
			}
		}

		//if result is between 50(inclusive) and 100(exclusive)
		else if(num >=50){
			if(num >= 90){
				printf("XC");
				num = num - 90;
			}
			else{
				printf("L");
				num = num - 50;
			}
		}

		//if result is between 10(inclusive) and 50(exclusive)
		else if(num >= 10){
			if(num >= 40){
				printf("XL");
				num = num - 40;
			}
			else{
				printf("X");
				num = num - 10;
			}
		}

		//if result is between 5(inclusive) and 10(exclusive).
		else if(num >=5){
			if(num == 9){
				printf("IX");
				num = num - 9;
			}
			else{
				printf("V");
				num = num - 5;
			}
		}

		else{
			if(num == 4){
				printf("IV");
				num = num - 4;
			}

			else{
				printf("I");
				num = num - 1;
			}

		}
	}

}
//End ToRoman

3. Screen shots

Screenshot from 2013-11-23 02:04:36

Leave a Reply

Your email address will not be published. Required fields are marked *