Hey forum, our professor assigned us a program we have to write in assembly language and I would love to have help on it.
Write an upper-to-lower case and lower-to-upper case conversion program.
When the user inputs a letter, your program should convert it to upper case if it is in lower case, or to lower case if it is a capital letter. Continue converting and displaying the results until the user presses the ‘enter’ key with no input. (You can do these conversions by adding or subtracting the appropriate hex value. Check your ASCII chart).
If the user inputs a key that is not A-Z or a-z, display a warning. When the user presses the enter key the warning should disappear and the program goes back to waiting for the user to input another character.
Supply appropriate prompts to the user.
Now, I have some of it figured out until the Code Segment. I wrote my logic in a different language to show what I am trying to do down below.
Assembly Source
;
; INSERT NAME HERE
;
PAGE 80,140
TITLE LAB2-PROGRAM TO ACCEPT A STRING AND CONVERT ALL CHARACTERS TO UPPERCASE
;
STACKSG SEGMENT PARA STACK
DW 32 DUP(?)
STACKSG ENDS
;
DATASG SEGMENT PARA
STRING LABEL BYTE
MAX DB 18 ;maximum input length
ACTUAL DB ?
DATASTR DB 20 DUP(' ') ;size is inputlength+2
DATASG ENDS
;
CODESG SEGMENT PARA
BEGIN PROC FAR ;Start main procedure
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:NOTHING
MOV AX,DATASG ;Set up DS and ES to point
MOV DS,AX ; to beginning of the
MOV ES,AX ; Data Segment
;<em>All logic code goes after this semi-colon.</em>
C++ Logic
#include <iostream>
using namespace std;
int main()
{
//Declare variables
char input = ' ';
cout << "Input a character to convert the case of it." << endl;
cout << "Type '!' to stop processing." << endl;
cout << endl;
while(input != '!')
{
//Get character to convert from user.
cin >> input;
//Check to see if input is UPPERCASE
if(input > 40 && input < 91)
{
cout << char(input + 32);
cout << endl;
}
//Or if input is LOWERCASE
else if(input > 60 && input < 123)
{
cout << char(input - 32);
cout << endl;
}
//If user did not input a character that can be converted.
else
{
if (input != '!')
{
cout << "Error! Try again.";
cout << endl;
}
}
}
system("pause");
return 0;
}
Now, if anyone would be willing to assist me I would greatly appreciate it! Thanks! :)
Now, if anyone would be willing to assist me I would greatly appreciate it!
I don't know what you need help with, since you have it all figured out.If you want us to write(or translate) your code for you, the forum rules wouldn't allow it.
You have to use software interrupt s to get input from keyboard and to print output to the screen. See Ralph Brown's Interrupt List .
Do some research on how to do your assignment and write your code.Post your code here even if it's broken, we'll help you to fix it.
Cheers and happy coding!
No I do not want code from you guys, I just need help figuring it out in Assembly. Would I loop until the user presses the enter key with no input? How would I test that condition using the proper syntax? I do not really understand JMP commands... :/
Would I loop until the user presses the enter key with no input?
I'm assuming that your program takes in a character(a-z or A-Z) and displays a character as output(and your c++ sample is doing the same thing). Here's the pseudocode(well.., kind of.)
-take user input
-if input==10(i.e.'\n'), then exit the program.
-if 65 <= input <= 90 then change it to lower case and print it and then jump back to take another input
-if 97<= input >= 122 then change it to upper case and print it and then jump back to take another input
-else then print the warning message, and again loopback to take the input. The ascii table might come in handy.
How would I test that condition using the proper syntax?
here's an example :
mov ah,8 ;dos function to get a character, the character is stored in 'al'
int 21h ;most important interrupt in dos,executes a system call to perform the above function
cmp al,10d ; check if user pressed <enter> key
je warning ;then print the warning message
;je means 'jump if equal' and 'warning is a label' Here's the intel x86 jmp instruction reference for you.
Tell me why the compare always goes to my error message please.
;
; DILLON SHEFFIELD
;
PAGE 80,140
TITLE LAB2-PROGRAM TO ACCEPT A STRING AND CONVERT ALL CHARACTERS TO UPPERCASE
;
STACKSG SEGMENT PARA STACK
DW 32 DUP(?)
STACKSG ENDS
;
DATASG SEGMENT PARA
ERROR DB 'Not a character. Sorry! Try again. '
DB '$'
PROMPT DB 'Enter a character to be converted.'
DB '$'
LIST LABEL BYTE
MAX DB 2 ;maximum input length
ACTUAL DB ?
DATASTR DB 1 DUP(' ') ;size is inputlength+2
DATASG ENDS
;
CODESG SEGMENT PARA
BEGIN PROC FAR ;Start main procedure
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:NOTHING
MOV AX,DATASG ;Set up DS and ES to point
MOV DS,AX ; to beginning of the
MOV ES,AX ; Data Segment
;
STARTHERE:
MOV AH, 09
LEA DX,PROMPT ;Display prompt to user to input character
INT 21H
MOV AH, 0AH
LEA DX, LIST ;Get input character from user.
INT 21H
CMP ACTUAL, 0 ;Compare the length to 0 to see if user gave a character
JE STOP ;If the user just did hit enter then stop processing
LEA AX, DATASTR ;Move the character into the AX register
MOV BX, 41H ;Move the hex value for 'A' into BX
CMP AX, BX ;Compare AX to BX
JB ERRORMSG ;If the character is below 'A' then go to error message
MOV BX, 61H ;Move 'a' into the BX register
CMP AX, BX ;Compare the input character to lowercase 'a'
JB TESTCAPITAL ;Jump below if the character is less than 'a'
TESTCAPITAL:
MOV BX, 5A ;Move capital 'Z' into BX
CMP AX, BX ;Compare the input character to uppercase 'Z'
JA ERRORMSG ;If the character is in the no-man-land part of the chart, display error.
JB CONLOW ;If it's between capital 'A' and 'Z' then convert to lower!
ERRORMSG:
MOV AH, 09
LEA DX,ERROR
INT 21H
JMP STARTHERE ;Go back up to top and grab another character
CONLOW:
ADD DATASTR, 20H;CONVERT from upper to lowercase!
MOV AH, 09
LEA DX, DATASTR
INT 21H
JMP STARTHERE ;Go back up to top and grab another character
CONUP:
ADD DATASTR, 20H;CONVERT from upper to lowercase!
MOV AH, 09
LEA DX, DATASTR
INT 21H
JMP STARTHERE ;Go back up to top and grab another character
STOP:
;
NOP ;Dummy instruction - stop DEBUG here
MOV AH,4CH ;Return to DOS
INT 21H ;via service call 4CH
BEGIN ENDP ;End procedure
CODESG ENDS ;End code segment
END BEGIN ;End source codeTell me why the compare always goes to my error message please.
See line 42 in your code.
LEA AX, DATASTR ;Move the character into the AX register
It is actually copying the offset address of 'DATASTR' to AX, not the character itself.Instead do like this:
LEA BX,DATASTR ;load the addr of character into the BX register
MOV SI,0 ;SI=0
CMP BYTE PTR [BX+SI],'A' ;Compare the character to 'A'
JB ERRORMSG ;If the character is below 'A' then go to error message
CMP BYTE PTR[BX+SI],'a' ;Compare the input character to lowercase 'a'
JB TESTCAPITAL ;Jump below if the character is less than 'a'
Here, BX is used to load the offset address, because it's the only general purpose register allowed to do so in real mode assembly.
Similarly, your 'TESTCAPITAL' will look like this:
TESTCAPITAL:
CMP BYTE PTR [BX+SI],'Z';Compare the input character to uppercase 'Z'
JA ERRORMSG ;If the character is in the no-man-land part of the chart, display error.
JB CONLOW ;If it's between capital 'A' and 'Z' then convert to lower!
and your CONLOW
CONLOW:
ADD BYTE PTR[BX+SI], 20H;CONVERT from upper to lowercase!
mov AH,06h ;DOS function to print a character
mov DL,[BX+SI] ;Print the character
INT 21H
If you want to use
MOV AH,09H
LEA DX,DATASTR
INT 21H
then, you have to setup your buffer like this:
MAX DB 2 ;maximum input length
ACTUAL DB ?
DATASTR DB 1 DUP(' ') ;size is inputlength+2
DB '$' ;end of string(required to use AH=09H function) Do that and we'll see.
P.S. It would've been much easier to read and write characters with 'AH=01H' and 'AH=02H' functions.
If you want to use Assembly Syntax (Toggle Plain Text) MOV AH,09H LEA DX,DATASTR INT 21H then, you have to setup your buffer like this: Assembly Syntax (Toggle Plain Text) MAX DB 2 ;maximum input length ACTUAL DB ? DATASTR DB 1 DUP(' ') ;size is inputlength+2 DB '$' ;end of string(required to use AH=09H function)
I tried that and it does not work, HOWEVER, the other method you supplied me works. Thank you so much.
BYTE PTR [BX+SI]
What does this do exactly though? Sorry for my ignorance, I just started programming Assembly about 2 months ago.
What does this do exactly though?BYTE PTR [BX+SI]
Si is an index register, though in the above code SI always remains zero since you had only one character (to access) in the string.While using instructions like CMP and ADD, you need to use the pointer directive 'BYTE PTR' to tell the assembler that the pointer contains a 8-bit value(or you want to access a byte). Similarly, there are other directives like 'WORD PTR','DWORD PTR' etc.So the above code is equivalent to
char *ptr="A";//BX points to the character in the buffer just like ptr here
int i=0;//SI is similar to this i
printf("%c\n",*(ptr+i));//prints the character