converting lower case to uppercase in assembler, noobie here looking for help

Started by cruachan, March 15, 2005, 04:55:22 PM

Previous topic - Next topic

cruachan

I am learning assmbly language on the MIPS processor and have to admit that I am finding it quite difficult. I am attempting this question - "console asks the user to enter a string of up to 20 characters then prints out the string, capitalizing all letters.

I know how to prompt the user to enter text and have the mips processor read what has been written but the actual change to capitals has me a bit stumped. Any help???

arafel

To capitalize an ascii character you need to subtract 0x20 from the lowercase character (i.e. "a"=0x61, "A"=0x41). Basically check the character that it's indeed a lowercase letter (values 0x61 to 0x7a) and subtract 0x20 from it.

pbrennick

Actually, arafel has given you an x86 answer to a VLSI or RISC question by accident.  There is no guarantee that this processor is using the same ascii character values.  In fact, I bet it doesn't.  It would be safer to:

subu $d, $s, $t

Where $s needs to contain the value of the distance between 'a' and 'A' in hex,  $t contains 'a' and $d will contain 'A'

If you cannot figure that out, tell me where I can view the ascii character set and I will figure it out for you.

BTW:  You are not squeemish are you, this is no easy undertaking, this programming in MIPS.

I hope this helps.
Paul

arafel

Hmm... I thought ascii character set is identical on MIPS and x86.

cruachan

Thanks for the replies guys, you can find the ascii table on http://www.lookuptables.com/. Anyway, this is as far as I can get:

.text
.global__start
start.
la $a0, prompt #the prompt would say something like "enter word", the user would type "hello"
li $v0, 4
syscall
li $vo, 5 #this is where the mips reads the users input
syscall

ÇódèKñïght

I am also learning MIPS assembly it uses the same ascii character set , you have to use syscall with 4 in v0 to print and address of the string in a0 ,to read string syscall with 8 in v0 address of buffer in a0 length of buffer in a1 .


.data
mystring: .asciiz ""
nextline: .asciiz "\n"
.text
main:
#taking input
li $v0,8
li $a1,20
la $a0,mystring
syscall

li $v0,4
li $t0,0

#looping through the string

loop: lb $t1,mystring($t0)
beq $t1,0,exit
sub $t1,$t1,32
sb $t1,mystring($t0)
addi $t0,$t0,1
j loop



#print final string
exit:
li $v0,4
la $a0,mystring
syscall

#end program

li $v0,10
syscall

pbrennick

Hi CodeKnight,
Why are you using sub over subu (unsigned)  For instance, 'A' is a positive value and 'a' is a negative value.  If you use a signed subtract wont you get unexpected results?

Also,

sub $t1, $t1, 32

Does this mean you are willing to trash the source and use it as the destination?  When you have 32 registers to play with, why do that?

nice looking example, though.

arafel,
Looks like you had the right idea all along!  :U

Paul

ÇódèKñïght

>Why are you using sub over subu (unsigned)
see the code above the loop section , i am using here
lb $t1,mystring($t0) to load byte ,lb loads the specified byte
with sign extended and load it in the specified register so t1 has signed
value in this case that's why i am performing signed subtraction. I have
already check the code and it runs fine.

>sub $t1, $t1, 32
>Does this mean you are willing to trash the source and use it as the destination?  When you have 32 >registers to play with, why do that?

yes i could have saved the result in another register but i don't see any point here in preserving old
value.

regards
PS: Sorry for late reply


pbrennick

Just curious, I am sure you checked it and it works but IMO it is not good programming habits.  That is just my opinion, though, and I respect yours.

Paul

hitchhikr

You can also consume a little bit of memory (512 bytes) and use this table to convert in uppercase:


CharTableUpper: .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
.byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
.byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
.byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
.byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
.byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
.byte 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
.byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f
.byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
.byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
.byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
.byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
.byte 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf
.byte 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf
.byte 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef
.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff


and this one to convert in lower case:


CharTableLower: .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
.byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
.byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
.byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
.byte 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
.byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f
.byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
.byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
.byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
.byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
.byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
.byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
.byte 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf
.byte 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf
.byte 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef
.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff


just use the ascii byte as an offset to retrieve the correct value from the table.

You can also easily construct these two tables with a piece of code, of course.