Question

In: Computer Science

Calculator in Assembly Language (Please add comments to explain your steps) Description: You are responsible to...

Calculator in Assembly Language (Please add comments to explain your steps)

Description:

You are responsible to implement several assembly functions to perform the simple arithmetic calculations for 2 64-bit integers. These functions will use the C function signature but the main logic within this function should be inline assembly code using the ASM block similar to the assembly example shown in class.

Program Specification:

1. long mult ( long op1, long op2 )

- Can’t use the MUL/IMUL instructions, meaning you use ADD repeatedly

- If there are overflow, return the overflowed values in RAX register

2. long XOR ( long op1, long op2 )

- xor will return the result of bit exclusive OR of op1 / op2

- can use XOR instruction

3. long rotate ( long op1, long direction, long number_of_bits )

- rotate will perform logical bit-rotation of input operand (op1)

- direction = 0 for left and 1 for right

- number_of_bits will dictate how many bits to rotate left or right

- you need to use rcl and rcr assembly instructions

4. long factorial ( long op1 )

- Input a positive integer (>0) and return the result of op1!

- Must use a loop in ASM to compute the result (no recursion)

Program Checklist:

You will submit p1_64.cpp on canvas and a file named readme.p1 text file with any comments (e.g Windows or macOS, 64-bit compilers that you use and what work or not work about your code). You MUST be able to compile and run the program from the command line. If I can't test your program, you're not going to get much credit for your work!

For #1, rewrite mult to use loop. For #2 & 3, write a new function using my examples as a good starting point. Also add 2 new printf() statements to print out the results similar to the others. For #4, rewrite the factorial C code with inline assembly code using a loop. Remember to add the “q” suffix for 64-bit to the assembly instructions.

Sample output in this sequence:

Operand 1 = 10 x000000000000000a Operand 2 = 5 x0000000000000005

Add(): 15 x000000000000000f

XOR(): 15 x000000000000000f

Mult(): 50 x0000000000000032

Mod(): 0 x0000000000000000

ShiftL: 320 x0000000000000140

ShiftR: 0 x0000000000000000

RotateL: 320 x0000000000000140

RotateR:-6341068275337658368 xa800000000000000

Fact(): 3628800 x0000000000375f00

p1sample.cpp

/* CS47 - Project #1 template */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

/* Example - add function */

long add (long op1, long op2)

{

long output=0;

asm

(

"movq %1, %%rax;"

"addq %2, %%rax;"

: "=a" (output)

: "r" (op1), "r" (op2)

:

); /* add the second operand to eax, eax has result */

return output;

}

/*

1. long mult (long op1, long op2)

- Cant use the MULQ/IMULQ instructions, meaning you use ADD repeatedly

- If there are overflow, return the overflowed values in EAX register

*/

long mult (long op1, long op2)

{

long output=0;

asm

(

"movq %1, %%rax;"

"imulq %2, %%rax;"

: "=a" (output)

: "r" (op1), "r" (op2)

:

); /* multiple the second operand to eax, eax has result */

return output;

}

/*

2. long mod (long op1, long op2)

- mod will return the remainder of op1 / op2

- can use IDIVQ instruction

*/

long mod (long op1, long op2)

{

long output=0;

long local_op2=op2;

asm

(

"movq %1, %%rax;"

"movq %2, %%rbx;"

"cdq;"

"idivq %%rbx;"

"movq %%rdx, %%rax;"

: "=a" (output)

: "r" (op1), "r" (local_op2)

:

);

return output;

}

/*

3. long shift (long op1, long direction, long number_of_bits)

- shift will perform arithmetic (SAR or SAL) bit-shifting of the input operand (op1)

- direction = 0 for left and 1 for right

- number_of_bits will dictate how many bits to shift left or right

*/

long shift (long op1, long direction, long number_of_bits)

{

long output=0;

long is_left = direction == 0 ? 1 : 0;

// printf("direction=%ld\n",is_left);

/* move first operand to eax */

/* move direction flag to ebx */

/* move bit count to ecx, but use cl only on sar or sal commands */

/* check if 0 (Left) */

/* shift right if not 0 */

asm

(

"movq %1, %%rax;"

"movq %2, %%rbx;"

"movq %3, %%rcx;"

"cmpq $1, %%rbx;"

"jz Shift_Left ;"

"sarq %%cl, %%rax ;"

"jmp done;"

"Shift_Left:"

"salq %%cl, %%rax;"

"done:"

: "=a" (output)

: "r" (op1), "r" (is_left), "r" (number_of_bits)

:

);

return output;

}

/*

4. int factorial ( int op1 )

- Input a positive integer (>0) and return the result of op1!

- Must use a loop to compute the result (no recursion)

*/

long factorial (long n)

{

if (n == 1)

return 1;

else

return n * factorial(n - 1);

}

int main(int argc, char** argv)

{

long op1, op2, result;

op1 = op2 = result = 0;

if (argc != 3)

{

printf("Usage: %s op1 op2 (two integers)\n", argv[0]);

return 1;

}

op1 = atol(argv[1]);

op2 = atol(argv[2]);

printf("Operand 1 = %ld x%016lx Operand 2 = %ld x%016lx\n", op1,op1,op2,op2);

result = add(op1, op2);

printf("Add():\t%10ld x%016lx\n", result, result);

result = mult(op1, op2);

printf("Mult():\t%10ld x%016lx\n", result, result);

if (op2 == 0)

{

printf("Mod Error: Divide by 0\n");

result = 0;

}

else

{

result = mod(op1, op2);

printf("Mod():\t%10ld x%016lx\n", result, result);

}

if (op2 < 0)

{

printf("Error: Shift count must be >= 0\n");

result = 0;

}

else

{

result = shift(op1, 0, op2);

printf("ShiftL:\t%10ld x%016lx\n", result, result);

result = shift(op1, 1, op2);

printf("ShiftR:\t%10ld x%016lx\n", result, result);

}

if (op1 <= 0)

{

printf("Error: Factorial input must be a positive integer >=1\n");

result = 0;

}

else

{

result = factorial(op1);

printf("Fact():\t%10ld x%016lx\n\n", result, result);

}

return 0;

}

For MacOS, open a terminal window and use the command "gcc -o calc p1sample.cpp" to compile. To run "./calc 2 3" or any 2 numbers as input. If gcc is not available replace it with "clang" as the compiler.

For Windows, install gcc in your system, you can install the 64-bit mingw from -> http://mingw-w64.org/doku.php (Links to an external site.)

Once it is install, you need to open a Windows command prompt, add the path by this command "PATH=c:\MinGW\bin;%PATH%" (e.g. assume c:\MinGW is the install directory). Afterward, if you type gcc -o calc.exe p1sample.cpp After a successful compile, you can run by "calc 2 3" or any 2 numbers

Solutions

Expert Solution

add(long, long):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     QWORD PTR [rbp-32], rsi
        mov     QWORD PTR [rbp-8], 0
        mov     rax, QWORD PTR [rbp-24]
        mov     rdx, QWORD PTR [rbp-32]
        movq rax, %rax;addq rdx, %rax;
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
mult(long, long):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     QWORD PTR [rbp-32], rsi
        mov     QWORD PTR [rbp-8], 0
        mov     rax, QWORD PTR [rbp-24]
        mov     rdx, QWORD PTR [rbp-32]
        movq rax, %rax;imulq rdx, %rax;
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
mod(long, long):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     QWORD PTR [rbp-32], rsi
        mov     QWORD PTR [rbp-8], 0
        mov     rax, QWORD PTR [rbp-32]
        mov     QWORD PTR [rbp-16], rax
        mov     rax, QWORD PTR [rbp-24]
        mov     rdx, QWORD PTR [rbp-16]
        movq rax, %rax;movq rdx, %rbx;cdq;idivq %rbx;movq %rdx, %rax;
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
shift(long, long, long):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-24], rdi
        mov     QWORD PTR [rbp-32], rsi
        mov     QWORD PTR [rbp-40], rdx
        mov     QWORD PTR [rbp-8], 0
        cmp     QWORD PTR [rbp-32], 0
        jne     .L8
        mov     eax, 1
        jmp     .L9
.L8:
        mov     eax, 0
.L9:
        mov     QWORD PTR [rbp-16], rax
        mov     rax, QWORD PTR [rbp-24]
        mov     rdx, QWORD PTR [rbp-16]
        mov     rcx, QWORD PTR [rbp-40]
        movq rax, %rax;movq rdx, %rbx;movq rcx, %rcx;cmpq $1, %rbx;jz Shift_Left ;sarq %cl, %rax ;jmp done;Shift_Left:salq %cl, %rax;done:
        mov     QWORD PTR [rbp-8], rax
        mov     rax, QWORD PTR [rbp-8]
        pop     rbp
        ret
factorial(long):
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     QWORD PTR [rbp-8], rdi
        cmp     QWORD PTR [rbp-8], 1
        jne     .L12
        mov     eax, 1
        jmp     .L13
.L12:
        mov     rax, QWORD PTR [rbp-8]
        sub     rax, 1
        mov     rdi, rax
        call    factorial(long)
        imul    rax, QWORD PTR [rbp-8]
.L13:
        leave
        ret
.LC0:
        .string "Usage: %s op1 op2 (two integers)\n"
.LC1:
        .string "Operand 1 = %ld x%016lx Operand 2 = %ld x%016lx\n"
.LC2:
        .string "Add():\t%10ld x%016lx\n"
.LC3:
        .string "Mult():\t%10ld x%016lx\n"
.LC4:
        .string "Mod Error: Divide by 0"
.LC5:
        .string "Mod():\t%10ld x%016lx\n"
.LC6:
        .string "Error: Shift count must be >= 0"
.LC7:
        .string "ShiftL:\t%10ld x%016lx\n"
.LC8:
        .string "ShiftR:\t%10ld x%016lx\n"
.LC9:
        .string "Error: Factorial input must be a positive integer >=1"
.LC10:
        .string "Fact():\t%10ld x%016lx\n\n"
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        mov     DWORD PTR [rbp-36], edi
        mov     QWORD PTR [rbp-48], rsi
        mov     QWORD PTR [rbp-8], 0
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR [rbp-16], rax
        mov     rax, QWORD PTR [rbp-16]
        mov     QWORD PTR [rbp-24], rax
        cmp     DWORD PTR [rbp-36], 3
        je      .L15
        mov     rax, QWORD PTR [rbp-48]
        mov     rax, QWORD PTR [rax]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 1
        jmp     .L16
.L15:
        mov     rax, QWORD PTR [rbp-48]
        add     rax, 8
        mov     rax, QWORD PTR [rax]
        mov     rdi, rax
        call    atol
        mov     QWORD PTR [rbp-24], rax
        mov     rax, QWORD PTR [rbp-48]
        add     rax, 16
        mov     rax, QWORD PTR [rax]
        mov     rdi, rax
        call    atol
        mov     QWORD PTR [rbp-16], rax
        mov     rsi, QWORD PTR [rbp-16]
        mov     rcx, QWORD PTR [rbp-16]
        mov     rdx, QWORD PTR [rbp-24]
        mov     rax, QWORD PTR [rbp-24]
        mov     r8, rsi
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC1
        mov     eax, 0
        call    printf
        mov     rdx, QWORD PTR [rbp-16]
        mov     rax, QWORD PTR [rbp-24]
        mov     rsi, rdx
        mov     rdi, rax
        call    add(long, long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC2
        mov     eax, 0
        call    printf
        mov     rdx, QWORD PTR [rbp-16]
        mov     rax, QWORD PTR [rbp-24]
        mov     rsi, rdx
        mov     rdi, rax
        call    mult(long, long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC3
        mov     eax, 0
        call    printf
        cmp     QWORD PTR [rbp-16], 0
        jne     .L17
        mov     edi, OFFSET FLAT:.LC4
        call    puts
        mov     QWORD PTR [rbp-8], 0
        jmp     .L18
.L17:
        mov     rdx, QWORD PTR [rbp-16]
        mov     rax, QWORD PTR [rbp-24]
        mov     rsi, rdx
        mov     rdi, rax
        call    mod(long, long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC5
        mov     eax, 0
        call    printf
.L18:
        cmp     QWORD PTR [rbp-16], 0
        jns     .L19
        mov     edi, OFFSET FLAT:.LC6
        call    puts
        mov     QWORD PTR [rbp-8], 0
        jmp     .L20
.L19:
        mov     rdx, QWORD PTR [rbp-16]
        mov     rax, QWORD PTR [rbp-24]
        mov     esi, 0
        mov     rdi, rax
        call    shift(long, long, long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC7
        mov     eax, 0
        call    printf
        mov     rdx, QWORD PTR [rbp-16]
        mov     rax, QWORD PTR [rbp-24]
        mov     esi, 1
        mov     rdi, rax
        call    shift(long, long, long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC8
        mov     eax, 0
        call    printf
.L20:
        cmp     QWORD PTR [rbp-24], 0
        jg      .L21
        mov     edi, OFFSET FLAT:.LC9
        call    puts
        mov     QWORD PTR [rbp-8], 0
        jmp     .L22
.L21:
        mov     rax, QWORD PTR [rbp-24]
        mov     rdi, rax
        call    factorial(long)
        mov     QWORD PTR [rbp-8], rax
        mov     rdx, QWORD PTR [rbp-8]
        mov     rax, QWORD PTR [rbp-8]
        mov     rsi, rax
        mov     edi, OFFSET FLAT:.LC10
        mov     eax, 0
        call    printf
.L22:
        mov     eax, 0
.L16:
        leave
        ret

Related Solutions

**Add comments to existing ARM code to explain steps** Write an ARM assembly program to convert...
**Add comments to existing ARM code to explain steps** Write an ARM assembly program to convert temperatures from Celsius to Fahrenheit or from Fahrenheit to Celsius. Here are the two formulas for your reference. Use variable to read and store values. C= 5* (F - 32) / 9 F = (9 * C / 5 ) + 32 My code below: TempConvert.s LDR R8,=temperature LDR R1,[R8] LDR R8,=unit LDRB R2,[R8] LDR R8,=celsius LDRB R3,[R8] LDR R8,=fahrenheit LDRB R4,[R8] MOV R6,#9...
Using MIPS (MARS) - Assembly Language Assignment ( PLEASE USE COMMENTS TO DESCRIBE EACH STEP )...
Using MIPS (MARS) - Assembly Language Assignment ( PLEASE USE COMMENTS TO DESCRIBE EACH STEP ) Take input of name, the input of hours worked, and input of hourly wage, and use input of hourly wage and hours worked to calculate total paycheck and print Name, and paycheck.
Also please add comments on the code and complete in C and also please use your...
Also please add comments on the code and complete in C and also please use your last name as key. The primary objective of this project is to increase your understanding of the fundamental implementation of Vigenere Cipher based program to encrypt any given message based on the Vignere algorithm. Your last name must be used as the cipher key. You also have to skip the space between the words, while replicating the key to cover the entire message. Test...
**Add comments to existing ARM code to explain steps** Question that my code answers: Write an...
**Add comments to existing ARM code to explain steps** Question that my code answers: Write an ARM assembly program to calculate the value of the following function: f(y) = 3y^2 – 2y + 10 when y = 3. My Code below, that needs comments added: FunSolve.s LDR R6,=y LDR R1,[R6] MOV R2,#5 MOV R3,#6 MUL R4,R1,R1 MUL R4,R4,R2 MUL R5,R1,R3 SUB R4,R4,R5 ADD R4,R4,#8 st B st y DCD 3
Please use assembly language x86 Visual Studio Write a program to add the following word size...
Please use assembly language x86 Visual Studio Write a program to add the following word size numbers:15F2, 9E89, 8342, 99FF, 7130 using adc instruction and a loop. The result must be in DX, AX. Show the result in debug window.
Please answer with steps for BA II finc. calculator (not excel steps) a. You anticipate that...
Please answer with steps for BA II finc. calculator (not excel steps) a. You anticipate that you will need $1,500,000 when you retire 30 years from now. You just join a new firm and your first annual salary is $100,000 to be received one year from today. You also received one time signing bonus of $50,000 today. You decided that you will put all you signing bonus into your account plus you will contribute $X every year starting next year...
Hi this is Assembly Language MASM x86 program. Please write it in the language and please...
Hi this is Assembly Language MASM x86 program. Please write it in the language and please explain it with comments thank you Please answer it I really need help this question was refunded before so please answer. Thank you so much also these are two separate programs thank you. 1) Write a procedure to read in decimal or hex number (byte-sized) Then write a procedure using shifts and ANDS to convert the string to a binary number (if is backward,...
Make sure to include comments that explain all your steps (starts with #) Make sure to...
Make sure to include comments that explain all your steps (starts with #) Make sure to include comments that explain all your steps (starts with #) Write a program that prompts the user for a string (a sentence, a word list, single words etc.), counts the number of times each word appears and outputs the total word count and unique word count in a sorted order from high to low. The program should: Display a message stating its goal Prompt...
Please explain steps to find these answers on the TI 84 plus calculator: A machine used...
Please explain steps to find these answers on the TI 84 plus calculator: A machine used to fill gallon sized paint cans is regulated so that the amount of paint dispensed has a mean of 128 ounces and a standard deviation of 0.20 ounce. You randomly select 40 cans and carefully measure the contents. The same mean of the cans is 127.9 ounces. Does the machine need to be reset? Explain your reasoning.
The first program is to count the number of zeros in $3855. Please     add comments...
The first program is to count the number of zeros in $3855. Please     add comments to each line                 org   $1000 array     db $38, $55 ; data to be tested                      org $1100 zero_cnt ds.b   1 lp_cnt     ds.b   1              org   $1500              clr   zero_cnt       ;initialize the 0 count to 0              movb #16,lp_cnt                   ldd   array         again     lsrd             bcs   chk_end         ;             inc   zero_cnt chk_end   dec   lp_cnt                           bne   again                               swi                          end
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT