LC-3 to Hexadecimal - c

This program takes the input
1283
5105
and prints out the following, I was wondering how to do it the opposite way around so to take the LC-3 instruction as the input and display it in Hexadecimal as I've been stuck on that for quite awhile. Any help would be great !
`add r1,r2,r3
and r0,r4,r5`
 
#include<stdio.h>
#include<string.h>
#include<ctype.h>
int main(int arga, char *argb[]){
int str; //string
int firstReg=0;
int secondReg=0;
int opCode=0;
int reg=0; //register
char hexa[7]; //hexadecimal value
FILE *fp;
fp = fopen(argb[1],"r");
// Statement 1
while((fscanf(fp,"%s",hexa))!=EOF){
int x =0;
str = 0;
// Statement 2
for (;x<=3;x++){
switch(hexa[x]){
case '0': str = str|0;
break;
case '1': str = str|1;
break;
case '2': str = str|2;
break;
case '3': str = str|3;
break;
case '4': str = str|4;
break;
case '5': str = str|5;
break;
case '6': str = str|6;
break;
case '7': str = str|7;
break;
case '8': str = str|8;
break;
case '9': str = str|9;
break;
case 'a': str = str|10;
break;
case 'b': str = str|11;
break;
case 'c': str = str|12;
break;
case 'd': str = str|13;
break;
case 'e': str = str|14;
break;
case 'f': str = str|15;
break;
default: printf("\nInvalid hexadecimal digit %c ",hexa[x]); return 0;
}
if(x != 3){
str = str <<4;
}
}
opCode = str&(15<<12);
opCode = opCode>>12;
// Statement 3
if(opCode == 5){
printf("and");
reg= str&(7<<9);
reg= reg>>9;
printf(" r%d",reg);
firstReg =str & (7<<6);
firstReg= firstReg>>6;
printf(", r%d",firstReg);
secondReg = str &(7);
printf(", r%d",secondReg);
printf("\n");
}
// Statement 4
if(opCode == 1) {
printf("add");
reg= str&(7<<9);
reg= reg>>9;
printf(" r%d",reg);
firstReg =str & (7<<6);
firstReg= firstReg>>6;
printf(", r%d",firstReg);
secondReg = str &(7);
printf(", r%d",secondReg);
printf("\n");
}
}
fclose(fp);
return 0;
}

Related

switch/case not recognizing certain char inputs

I am creating a program for an online coding course which takes a poker hand and calculates the odds of the hand winning. I am currently in the early stages, writing the functions necessary to advance to the next part of the assignment. I have isolated my issues to one function, card_from_letters.
I created my-test-main.c to test card_from_letters. It creates two chars, representing the suit and value of a poker card. It then creates the struct testCard2.
A card_t struct has two components: an unsigned int for value, and an enumerated type for suit between SPADES and CLUBS. I cannot change the struct card_t.
int main(void) {
char sui = 'c';
char val = 'Q';
card_t testCard2 = card_from_letters(val, sui);
printf("last test! My card %c%c is value %d, and suit %d!\n", val, sui, testCard2.value, testCard2.suit);
}
This is my function card_from_letters:
card_t card_from_letters(char value_let, char suit_let) {
card_t temp;
assert(suit_let == 'd' ||'h' || 'c' || 's');
assert((value_let >= '2' && value_let <= '9') || (value_let = '0' || 'K' || 'Q' || 'J' || 'A'));
switch (value_let) {
case '2': temp.value = 2; break;
case '3': temp.value = 3; break;
case '4': temp.value = 4; break;
case '5': temp.value = 5; break;
case '6': temp.value = 6; break;
case '7': temp.value = 7; break;
case '8': temp.value = 8; break;
case '9': temp.value = 9; break;
case '0': temp.value = 10; break;
case 'K': temp.value = 13; break;
case 'Q': temp.value = 12; break;
case 'J': temp.value = 11; break;
case 'A': temp.value = 14; break;
}
switch (suit_let) {
case 's': temp.suit = SPADES; break;
case 'h': temp.suit = HEARTS; break;
case 'd': temp.suit = DIAMONDS; break;
case 'c': temp.suit = CLUBS; break;
}
return temp;
}
When val is set between '2' and '9', I am able to run card_from_letters with no problem. When I run my-test-main.c as it is here through gdb, the execution arrow makes it to switch (value_let), but then skips all cases and enters switch (suit_let), where it returns the correct suit. What am I missing here? How come card_from_letters works for chars 2 to 9, but not 0 to A?

How to get rid of the Heap-corruption error (Critical error c0000374) in C when converting hex into binary string?

Part of my project, where we have to take an input file with hex numbers and convert them to MIPS code, I want to convert the hex into binary so it'd be easier for me to convert it into MIPS. However, when I run the code, it crashes and quits when it reaches the part where it calls the converter function. GDB says its a critical error c0000374. How do I fix this?
I have tried giving the target string more space and it doesn't seem to have any effect. I have also tried using malloc to no avail.
char* convertBinary (int hex)
{
char* hexdec = calloc(9, sizeof(char));
char* bin = calloc(SIZE+1, sizeof(char));
snprintf(hexdec, SIZE, "%08X", hex);
long int i;
for (i = 0; hexdec[i]; ++i)
{
switch (hexdec[i])
{
case '0':
strcat(bin, "0000");
break;
case '1':
strcat(bin, "0001");
break;
case '2':
strcat(bin, "0010");
break;
case '3':
strcat(bin, "0011");
break;
case '4':
strcat(bin, "0100");
break;
case '5':
strcat(bin, "0101");
break;
case '6':
strcat(bin, "0110");
break;
case '7':
strcat(bin, "0111");
break;
case '8':
strcat(bin, "1000");
break;
case '9':
strcat(bin, "1001");
break;
case 'A':
case 'a':
strcat(bin, "1010");
break;
case 'B':
case 'b':
strcat(bin, "1011");
break;
case 'C':
case 'c':
strcat(bin, "1100");
break;
case 'D':
case 'd':
strcat(bin, "1101");
break;
case 'E':
case 'e':
strcat(bin, "1110");
break;
case 'F':
case 'f':
strcat(bin, "1111");
break;
default:
printf("\nInvalid hexadecimal digit %c",
hexdec[i]);
}
}
return bin;
}
Also, in case it helps, here is the main function where I call this function
int main ()
{
int command = 10010100; //This is in hex
char* binaryString = convertBinary(command);
printf("The coverted binary is: %s\n", binaryString);
}
I expect the function to return a string of the binary numbers that have been converted from an 8 digit hex number. However, the program just quits and doesn't output anything. When debugged with GDB, it lays out a warning saying,
warning: Critical error detected c0000374
There are multiple problems in your code:
You do not check the for memory allocation failure.
Since you allocate 9 bytes for hexdec, snprintf(hexdec, SIZE, "%08X", hex); should be
snprintf(hexdec, 9, "%08X", hex);
The definition of SIZE is missing, as well as the #include lines. Post the complete source of the program exhibiting the offending behavior.
There is no need to loop until the end of the string hexdec: since you convert the hex value with %08X, just loop with:
for (i = 0; i < 8; ++i)
You should free(hexdec) before leaving the convertBinary function.
The code and comment do not agree in int command = 10010100; //This is in hex, which one is wrong? Probably both.
There is no need to use long type for i, int will suffice. Conversely, the argument hex should have unsigned int type.
Here is a simplified version of your code:
#include <stdio.h>
#include <stdlib.h>
char *convertBinary(unsigned int hex) {
char *bin = calloc(33, 1);
int i;
if (bin) {
for (i = 32; i-- > 0;) {
bin[i] = '0' + (hex & 1);
hex >>= 1;
}
}
return bin;
}
int main() {
int command = 0x10010100; //This is in hex
char *binaryString = convertBinary(command);
if (binaryString == NULL) {
printf("Memory allocation failure\n");
} else {
printf("The converted binary is: %s\n", binaryString);
free(binaryString);
}
return 0;
}

unexpected output from switch statement in c program [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'm getting output of a - 0000520 when I input a while i should get 0001010 as per the code I've assigned. Also the default runs every time (tested using a printf statement) for unexplained reason. My code is here:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int splitWord(char* word, int count);
int sunCode(char letter);
int main()
{
char inputString[100];
char splitStrings[10][10];
int i, j, count;
printf("Enter the message.\n");
fgets(inputString, 100, stdin);
j = count = 0;
for (i = 0; i <= (strlen(inputString)); i++) {
if (inputString[i] == ' ' || inputString[i] == '\0') {
splitStrings[count][j] = '\0';
count++;
j = 0;
}
else {
splitStrings[count][j] = inputString[i];
j++;
}
}
printf("\nOriginal String is: %s\n", inputString);
for (i = 0; i < count; i++) {
/*for(j=0;j<=strlen(splitStrings[i]);j++){
printf("%s",splitStrings[i][j]);
}*/
splitWord(splitStrings[i], count);
}
return 0;
}
int splitWord(char* word, int count)
{
int i;
int strLength = strlen(word);
for (i = 0; i <= strLength; i++) {
sunCode(word[i]);
// printf("%c\n",word[i]);
}
return 0;
}
int sunCode(char letter)
{
char letr = tolower(letter);
int code = 0;
switch (letr) {
case '0':
code = 0000000;
break;
case '1':
code = 0000001;
break;
case '2':
code = 0000010;
break;
case '3':
code = 0000011;
break;
case '4':
code = 0000100;
break;
case '5':
code = 0000101;
break;
case '6':
code = 0000110;
break;
case '7':
code = 0000111;
break;
case '8':
code = 0001000;
break;
case '9':
code = 0001001;
break;
case 'a':
code = 0001010;
break;
case 'b':
code = 0001011;
break;
case 'c':
code = 0001100;
break;
case 'd':
code = 0001101;
break;
case 'e':
code = 0001110;
break;
case 'f':
code = 0001111;
break;
case 'g':
code = 0010000;
break;
case 'h':
code = 0010001;
break;
case 'i':
code = 0010010;
break;
case 'j':
code = 0010011;
break;
case 'k':
code = 0010100;
break;
case 'l':
code = 0010101;
break;
case 'm':
code = 0010110;
break;
case 'n':
code = 0010111;
break;
case 'o':
code = 0011000;
break;
case 'p':
code = 0011001;
break;
case 'q':
code = 0011010;
break;
case 'r':
code = 0011011;
break;
case 's':
code = 0011100;
break;
case 't':
code = 0011101;
break;
case 'u':
code = 0011110;
break;
case 'v':
code = 0011111;
break;
case 'w':
code = -010000;
break;
case 'x':
code = 010001;
break;
case 'y':
code = 010010;
break;
case 'z':
code = 010011;
break;
case ' ':
code = 45;
printf("\nis space\n");
break;
default:
break;
}
printf("%c - %07d\n", letr, code);
}
I tried to see if it's giving ASCII values (it isn't)
the letter is being passed properly in the sunCode function (it is)
I do not understand why it is behaving like this, verified the syntax and conditions of switch too.
I am using gcc 7.3.0 on Ubuntu.
Leading zeros indicate that the number is expressed in octal, or base 8; thus, 010 = 8.
https://stackoverflow.com/a/1661378/10479742
0001010 in octal is 520 in decimal, and that's why you get that result. Either remove leading zeros, or change code to string.

Console input in 32-bit Protected mode

I am currently working on my OS. I've started building it since a-day before yesterday. My OS is command-based.
This is my Kernel.c(The main file):
#include "include/screen.h"
#include "include/kb.h"
#include "include/string.h"
#include "data/userdata.c"
kmain()
{
clearScreen();
print("Halcyon OS 1.05 Beta ");
while (1)
{
print("\nhalcyon#halcyon ~\n$ ");
string ch = readStr();
if(strEql(ch,"cmd")!=0)
{
print("\nYou are already in cmd\n");
}
else if(strEql(ch,"clear")!=0)
{
clearScreen();
}
else if(strEql(ch,"help")!=0)
{
print("Halcyon help.");
}
else if(strEql(ch,"")!=0)
{
continue;
}
else
{
print("\nNo command found:");print(ch);
break;
}
}// end while loop!
}
And here is kb.h (I've made it for keyboard support.):
#ifndef KB_H
#define KB_H
#include "screen.h"
#include "system.h"
#include "types.h"
string readStr()
{
char buff;
string buffstr;
uint8 i = 0;
uint8 reading = 1;
while(reading)
{
if(inportb(0x64) & 0x1)
{
switch(inportb(0x60))
{
/*case 1:
printch('(char)27); Escape button
buffstr[i] = (char)27;
i++;
break;*/
case 2:
printch('1');
buffstr[i] = '1';
i++;
break;
case 3:
printch('2');
buffstr[i] = '2';
i++;
break;
case 4:
printch('3');
buffstr[i] = '3';
i++;
break;
case 5:
printch('4');
buffstr[i] = '4';
i++;
break;
case 6:
printch('5');
buffstr[i] = '5';
i++;
break;
case 7:
printch('6');
buffstr[i] = '6';
i++;
break;
case 8:
printch('7');
buffstr[i] = '7';
i++;
break;
case 9:
printch('8');
buffstr[i] = '8';
i++;
break;
case 10:
printch('9');
buffstr[i] = '9';
i++;
break;
case 11:
printch('0');
buffstr[i] = '0';
i++;
break;
case 12:
printch('-');
buffstr[i] = '-';
i++;
break;
case 13:
printch('=');
buffstr[i] = '=';
i++;
break;
case 14:
printch('\b');
i--;
buffstr[i] = 0;
break;
/* case 15:
printch('\t'); Tab button
buffstr[i] = '\t';
i++;
break;*/
case 16:
printch('q');
buffstr[i] = 'q';
i++;
break;
case 17:
printch('w');
buffstr[i] = 'w';
i++;
break;
case 18:
printch('e');
buffstr[i] = 'e';
i++;
break;
case 19:
printch('r');
buffstr[i] = 'r';
i++;
break;
case 20:
printch('t');
buffstr[i] = 't';
i++;
break;
case 21:
printch('y');
buffstr[i] = 'y';
i++;
break;
case 22:
printch('u');
buffstr[i] = 'u';
i++;
break;
case 23:
printch('i');
buffstr[i] = 'i';
i++;
break;
case 24:
printch('o');
buffstr[i] = 'o';
i++;
break;
case 25:
printch('p');
buffstr[i] = 'p';
i++;
break;
case 26:
printch('[');
buffstr[i] = '[';
i++;
break;
case 27:
printch(']');
buffstr[i] = ']';
i++;
break;
case 28:
// printch('\n');
// buffstr[i] = '\n';
i++;
reading = 0;
break;
/* case 29:
printch('q'); Left Control
buffstr[i] = 'q';
i++;
break;*/
case 30:
printch('a');
buffstr[i] = 'a';
i++;
break;
case 31:
printch('s');
buffstr[i] = 's';
i++;
break;
case 32:
printch('d');
buffstr[i] = 'd';
i++;
break;
case 33:
printch('f');
buffstr[i] = 'f';
i++;
break;
case 34:
printch('g');
buffstr[i] = 'g';
i++;
break;
case 35:
printch('h');
buffstr[i] = 'h';
i++;
break;
case 36:
printch('j');
buffstr[i] = 'j';
i++;
break;
case 37:
printch('k');
buffstr[i] = 'k';
i++;
break;
case 38:
printch('l');
buffstr[i] = 'l';
i++;
break;
case 39:
printch(';');
buffstr[i] = ';';
i++;
break;
case 40:
printch((char)44); // Single quote (')
buffstr[i] = (char)44;
i++;
break;
case 41:
printch((char)44); // Back tick (`)
buffstr[i] = (char)44;
i++;
break;
/* case 42: Left shift
printch('q');
buffstr[i] = 'q';
i++;
break;
case 43: \ (< for somekeyboards)
printch((char)92);
buffstr[i] = 'q';
i++;
break;*/
case 44:
printch('z');
buffstr[i] = 'z';
i++;
break;
case 45:
printch('x');
buffstr[i] = 'x';
i++;
break;
case 46:
printch('c');
buffstr[i] = 'c';
i++;
break;
case 47:
printch('v');
buffstr[i] = 'v';
i++;
break;
case 48:
printch('b');
buffstr[i] = 'b';
i++;
break;
case 49:
printch('n');
buffstr[i] = 'n';
i++;
break;
case 50:
printch('m');
buffstr[i] = 'm';
i++;
break;
case 51:
printch(',');
buffstr[i] = ',';
i++;
break;
case 52:
printch('.');
buffstr[i] = '.';
i++;
break;
case 53:
printch('/');
buffstr[i] = '/';
i++;
break;
case 54:
printch('.');
buffstr[i] = '.';
i++;
break;
case 55:
printch('/');
buffstr[i] = '/';
i++;
break;
/*case 56:
printch(' '); Right shift
buffstr[i] = ' ';
i++;
break;*/
case 57:
printch(' ');
buffstr[i] = ' ';
i++;
break;
}
}
}
buffstr[i] = 0;
return buffstr;
}
#endif
And at last the string.h(This has function to compare two strings.):
#ifndef STRING_H
#define STRING_H
#include "types.h"
uint16 strlength(string ch)
{
uint16 i = 1;
while(ch[i++]);
return --i;
}
uint8 strEql(string ch1,string ch2)
{
uint8 result = 1;
uint8 size = strlength(ch1);
if(size != strlength(ch2)) result =0;
else
{
uint8 i = 0;
for(i;i<=size;i++)
{
if(ch1[i] != ch2[i]) result = 0;
}
}
return result;
}
#endif
But the problem is that even if enter the correct command like 'cmd', it only sometimes says 'No command found: cm' and sometimes it works! It goes sometimes correct and says: 'You're already in cmd!'
Also, it is recognizing it as 'cm' not 'cmd'.
And if I write in kernel.c: "print("Hello");" then it will print: 'Hell' not 'Hello'! It misses the last character.
I don't know what's wrong with my program.
I use gcc to compile it, platform is Linux Ubuntu. The sometimes work and sometimes not. But if I compile my kernel with Windows the command never works.
Please help! Any help will be greatly appreciated.
Your string length function is wrong:
uint16 strlength(string ch)
{
uint16 i = 1;
while(ch[i++]);
return --i;
}
Assuming the string is "cmd", then you start and check if the second character, m, is null, then the third, then finally the fourth is null. i starts off with 1 and increases up to 3, and finally gets decremented to 2.
Also it would fail on zero length strings.
The consequence is, that you are not printing enough in your print function.
unit16 strlength(string ch) {
unit16 l = 0;
while (ch[l]) {
++l;
}
return l;
}
To find out why the comparison fails I'd need to know what type string actually is.
If it's a char *, then this is actually undefined behaviour, as your writing into some random memory.
If it's a char [N] then out won't work either, because that array decays to a pointer on return. And that pointer points to a local variable with automatic storage, so it is no longer valid after function return.
OK, it's a pointer. Pointers point to memory, where you then store the actual data. To have this working you need
Memory to store the data to
Set the pointer to point to that memory.
Normally one would allocate memory via malloc, but in the context of operating system development you'd first have to implement that yourself.
You cold use a buffer with automatic storage (on the stack) in the caller:
char buffer[20];
size_t num_read = read_into(buffer, 20);
// pass the pointer to the memory for the data plus the maximal characters this buffer can hold.
size_t read_into (char * buffer, size_t max) {
// read up to Max characters into the
// buffer, don't forget to count the 0 at the end.
}
Judging from the rest of your code, you seem to be fairly new to C programming. While writing an operating system kernel is a fun task, you'll have more fun doing it when you understand the basics first.
Since you're writing to random memory locations with those uninitialised char * you don't know where you store the data. This could be "normal", free memory. Then everything will work as expected. But you could also write to memory mapped device information or even your own code, making it impossible to predict what might happen.

Nested switch leads to an infinite loop

In the following program, I need to change the initial and final characters to their respective characters as mentioned below in case but this is giving me an infinite loop. What should I do to fix it?
int main(void)
{
char state ='t';
char word[20]="aaabbccaaaaccbbb";
int initiallength = strlen(word)-1; strcat(word,"a");
while(strlen(word)-1 >initiallength)
{
switch(state)
{
case 't':
switch(word[strlen(word)-1])
{
case 'a':
word[strlen(word)-1]='b'; break;
case 'b':
word[strlen(word)-1]='c'; break;
case 'c':
word[strlen(word)-1]='d'; break;
case 'd':
word[strlen(word)-1]='\0'; break;
}
switch(word[0])
{
case 'a':
word[0]='b'; break;
case 'b':
word[0]='c'; break;
case 'c':
word[0]='d'; break;
case 'd':
word[0]='\0'; break;
}
}
}
}
If I understand correctly what you want to do is swap the first and last characters in the given string. If that's the case first your code is way too complicated and second the reason you're getting an infinite loop is because the condition strlen(word)-1 >initiallength is always true.
Test if word is empty
int main(void){
char state ='t';
char word[20]="aaabbccaaaaccbbb";
int initiallength = strlen(word)-1;
strcat(word,"a");
while(strlen(word)-1 >initiallength && strlen(word) >= 0){
printf("%d %d\n", strlen(word)-1, initiallength);
printf("%d len %s\n", strlen(word), word);
switch(state){
case 't':
switch(word[strlen(word)-1]){
case 'a':
case 'b':
case 'c':
word[strlen(word)-1]++;
break;
case 'd':
word[strlen(word)-1] = '\0';
break;
}
switch(word[0]){
case 'a':
case 'b':
case 'c':
word[0]++;
break;
case 'd':
word[0] = '\0';
break;
}
}
}
}

Resources