Instructions
Objective
Write an Assembly language assignment program to shift string by n bits in .
Requirements and Specifications
You are responsible for writing an assembly function for an encryption library. This function will encrypt or decrypt a string of characters. It will use a simple ciphertext algorithm which does character shifting. This function will use the C function signature but everything within this function should be assembly code using the ASM block similar to the assembly example shown in class. This function should be built into a separate shared library (e.g. .DLL or .so). p3.cpp will contain the calling function and should not be modified.
Program Specification:
long s_encrypt (char *src, char* dest, long en_flag);
src – the original string
dest – the output string
en_flag – 0 for encryption and 1 for decryption
This function returns the # of characters being changed in the string. If there is no change, it should return zero.
Screenshots of output


Source Code
/*
encrypt.cpp - This file contains the code to encrypt and decrypt an input string
and output the modified string.
*/
#include "key.h"
#include
long s_encrypt (char *src, char* dest, long en_flag);
void get_key (long *dir, long *count);
void set_key (long dir, long count);
void get_key (long *dir, long *count)
{
*dir = direction;
*count = shiftcount;
}
void set_key (long dir, long count)
{
direction = dir;
shiftcount = count;
}
long s_encrypt (char *src, char* dest, long en_flag)
{
long characters_changed = 0;
long len = strlen(src);
long count = shiftcount % 26; /* adjust shiftcount if > 26 */
long dir = direction;
asm
(
/* Add your ASM code here !! */
"movq %1, %%rsi;" // load source pointer
"movq %2, %%rdi;" // load destination pointer
"movq %3, %%r8;" // load flag
"movq %4, %%rcx;" // load string length
"movq $0, %%rax;" // set changed count to zero
"cmpq $0, %%rcx;" // if empty string
"je done;" // go to end
"movq %5, %%rdx;" // load shift count
"movq %6, %%r9;" // load direction
"addq $1, %%r9;" // increment direction to get 1 or 2
"cmpq $1, %%r9;" // if forward (1)
"je loop_start;" // then start
"movq $-1, %%r9;" // else set negative increment
"addq %%rcx, %%rsi;" // point to end of string
"decq %%rsi;" // point to last char in string
"loop_start:"
"movb (%%rsi), %%r10b;" // load character from source string
"cmpb $65, %%r10b;" // compare char with 'A'
"jl save;" // if < 'A' is not alpha, leave as it is
"cmpb $90, %%r10b;" // compare char with 'Z'
"jg checkLow;" // if > 'Z' is not upper case, might be lower
"addb $32, %%r10b;" // else, toggle to lower case
"movb $122, %%bl;" // save 'z' for comparison
"cmpq $0, %%r8;" // see if we need to encrypt
"je encrypt;" // if so, encrypt
"movb $97, %%bl;" // else, save 'a' for comparison
"jmp decrypt;" // jump to decryption part
"checkLow:"
"cmpb $97, %%r10b;" // compare char with 'a'
"jl save;" // if < 'a' is not alpha, leave as it is
"cmpb $122, %%r10b;" // compare char with 'z'
"jg save;" // if > 'z' is not alpha, leave as it is
"subb $32, %%r10b;" // else, toggle to upper case
"movb $65, %%bl;" // else, save 'A' for comparison
"cmpq $1, %%r8;" // see if we need to decrypt
"je decrypt;" // if so, encrypt
"movb $90, %%bl;" // save 'Z' for comparison
"encrypt:"
"incq %%rax;" // increment changed chars
"addb %%dl, %%r10b;" // shift by required amount
"cmpb %%bl,%%r10b;" // compare with 'z' or 'Z'
"jle save;" // if <= 'z' or 'Z', save
"subb $26,%%r10b;" // else, wrap around
"jmp save;" // save encrypted char
"decrypt:"
"incq %%rax;" // increment changed chars
"subb %%dl, %%r10b;" // shift by required amount
"cmpb %%bl,%%r10b;" // compare with 'a' or 'A'
"jge save;" // if >= 'a' or 'A', save
"addb $26,%%r10b;" // else, wrap around
"save:"
"movb %%r10b, (%%rdi);"
"add %%r9, %%rsi;" // advance to next char in source string
"inc %%rdi;" // advance to next char in destination string
"loop loop_start;" // repeat for all chars in source string
"done:"
"movb $0, (%%rdi);" // save ending zero in destination
: "=a" (characters_changed)
: "m" (src), "m" (dest), "m" (en_flag), "m" (len), "m" (count), "m" (dir)
:
);
return characters_changed;
}