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
;[I]All logic code goes after this semi-colon.[/I]

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 interrupts 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 code

Tell 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.

BYTE PTR [BX+SI]

What does this do exactly though?

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

Edited 5 Years Ago by D33wakar: n/a

This question has already been answered. Start a new discussion instead.