a function compare 2 string in mips - compare

this function should simply verify if the input is equal to the string simolo1
even if I input exactly the same string the output is strings are not equal.
I am saving in the registers s2 and s3 the pointers to the arrays. then I compare each byte, if all of those are equal the program should finish and output 'strings are equal'
.data
prompt: .asciiz "Enter string ('.' to end) > "
dot: .asciiz "."
eqmsg: .asciiz "strings are equal\n"
nemsg: .asciiz "strings are not equal\n"
str1: .space 80
str2: .space 80
simbolo1: .asciiz "sasso"
simbolo2: .asciiz "carta"
simbolo3: .asciiz "forbice"
.text
.globl main
main:
# get first string
la $s2,str1
move $t2,$s2
jal getstr
la $s3, simbolo1
# string compare loop (just like strcmp)
cmploop:
lb $t2,($s2) # get next char from str1
lb $t3,($s3) # get next char from str2
bne $t2,$t3,cmpne # are they different? if yes, fly
beq $t2,$zero,cmpeq # at EOS? yes, fly (strings equal)
addi $s2,$s2,1 # point to next char
addi $s3,$s3,1 # point to next char
j cmploop
# strings are _not_ equal -- send message
cmpne:
la $a0,nemsg
li $v0,4
syscall
j main
# strings _are_ equal -- send message
cmpeq:
la $a0,eqmsg
li $v0,4
syscall
j main
# getstr -- prompt and read string from user
#
# arguments:
# t2 -- address of string buffer
getstr:
# prompt the user
la $a0,prompt
li $v0,4
syscall
# read in the string
move $a0,$t2
li $a1,79
li $v0,8
syscall
# should we stop?
la $a0,dot # get address of dot string
lb $a0,($a0) # get the dot value
lb $t2,($t2) # get first char of user string
beq $t2,$a0,exit # equal? yes, exit program
jr $ra # return
# exit program
exit:
li $v0,10
syscall

Related

Printing a char that is inputted by the user, perhaps the way `cout` does it?

I'm trying to figure out how to print the char inputted by the user in assembly language. (Let's pretend that I already have the lowercase value and I want to print it on uppercase.)
lowercase DB "Input a letter: $"
uppercase DB "The uppercase equivalent of letter <the lowercase letter the user inputted> is: $"
In contrast, if it's written in c++, it would be:
cout << "The uppercase equivalent of letter" << lowercase << "is: " << endl"
How should I do it?
The preferred solution would be to insert "the lowercase letter the user inputted" in the output string. I see you already $-terminated the string so it can get printed all at once using the DOS.PrintString function 09h.
Define the uppercase string with a placeholding question mark (or any other character that you like):
uppercase db "The uppercase equivalent of letter ? is: $"
^
placeholder
For ease of addressing the placeholder, you can write the string on 2 lines, so you can put a label in front of the placeholder:
uppercase db "The uppercase equivalent of letter "
uppercase_ db "? is: $"
^
placeholder
Replace the placeholder by the lowercase letter from user input:
mov [uppercase_], al ; AL is lowercase
Print the string with DOS.PrintString function 09h:
mov dx, offset uppercase
mov ah, 09h
int 21h
What about displaying the capitalized letter?
No need to output it separately. The simplest solution is to also include it in the output string.
Just add a second placeholder right before the terminating $ character. Instead of splitting off a third line we can easily establish an offset by counting characters (The 2 placeholders are 6 characters apart):
uppercase db "The uppercase equivalent of letter "
uppercase_ db "? is: ?$"
^ ^
placeholder1 placeholder2
Replace both placeholders. At the ellipsis ... you must convert from lowercase to uppercase!
mov [uppercase_], al ; AL is lowercase
...
mov [uppercase_ + 6], al ; AL is uppercase
Print the string with DOS.PrintString function 09h.
mov dx, offset uppercase
mov ah, 09h
int 21h
For some background information about displaying text read this Q/A Displaying characters with DOS or BIOS. It has examples of printing strings of text character per character.
Bringing it more in line with what cout does
The above solution no longer holds true if the datum that needs to overwrite the placeholder is of varying lengths. Using a 5-character placeholder, consider:
db 'Your donation of € is much appreciated.$'
If the donated amount has 5 digits this will print out just fine:
Your donation of 20000 € is much appreciated.
but if the donated amount is small, it's no longer that nice to look out:
Your donation of 5 € is much appreciated.
In this scenario we'll have to use the different approach of outputting the accompanying texts separately from the number that goes in between.
ThankYou1 db 'Your donation of $'
ThankYou2 db ' € is much appreciated.$'
...
mov dx, offset ThankYou1
mov ah, 09h
int 21h
mov ax, [amount]
call DisplayNumber
mov dx, offset ThankYou2
mov ah, 09h
int 21h
For ideas about how to write the DisplayNumber routine, see Displaying numbers with DOS.

Perl regex substitutions with unicode character don't work, what am I missing?

I'm trying to 'fix' some files that have unexpected unicode characters using perl's regex with the '''\N{UNICODE NAME}''' construct. But for some reason that I don't understand fully, nothing happens, but there are no error messages.
Here is a simple test example.
[2007]$ read ZZ < test.txt && unum "${ZZ}"
Octal Decimal Hex HTML Character Unicode
0101 65 0x41 A "A" LATIN CAPITAL LETTER A
040 32 0x20 " " SPACE, SP
0341 225 0xE1 á "á" LATIN SMALL LETTER A WITH ACUTE
040 32 0x20 " " SPACE, SP
0334 220 0xDC Ü "Ü" LATIN CAPITAL LETTER U WITH DIAERESIS
040 32 0x20 " " SPACE, SP
0321 209 0xD1 Ñ "Ñ" LATIN CAPITAL LETTER N WITH TILDE
040 32 0x20 " " SPACE, SP
040 32 0x20 " " SPACE, SP
062745 26085 0x65E5 日 "日" CJK UNIFIED IDEOGRAPH-#65E5, IRGKangXi=0489.010, RSKangXi=72.0, Def{sun; day; daytime}
063454 26412 0x672C 本 "本" CJK UNIFIED IDEOGRAPH-#672C, IRGKangXi=0509.070, RSKangXi=75.1, Def{root, origin, source; basis}
0105236 35486 0x8A9E 語 "語" CJK UNIFIED IDEOGRAPH-#8A9E, IRGKangXi=1163.080, RSKangXi=149.7, Def{language, words; saying, expression}
040 32 0x20 " " SPACE, SP
061 49 0x31 1 "1" DIGIT ONE
040 32 0x20 " " SPACE, SP
040 32 0x20 " " SPACE, SP
0177421 65297 0xFF11 1 "1" FULLWIDTH DIGIT ONE
040 32 0x20 " " SPACE, SP
040 32 0x20 " " SPACE, SP
057 47 0x2F &sol; "/" SOLIDUS
040 32 0x20 " " SPACE, SP
040 32 0x20 " " SPACE, SP
0137 95 0x5F &lowbar;,&UnderBar; "_" LOW LINE
Now, when I try and replace one character as a test using perl inline, eg
[2008]$ perl -p -e 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á Ü Ñ 日本語 1 1 / _
There's no error, but no substitution either. I also tried,
[2013]$ perl -e 'BEGIN { use charnames q{:full}; }' -p -e 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á Ü Ñ 日本語 1 1 / _
with no change.
What am I missing, the documentation seems to imply that this should work?
If I make a direct substitution it works as expected,
[2015]$ perl -p -e 's/日+/X/gu;' test.txt
A á Ü Ñ X本語 1 1 / _
You have to tell perl that the input is in UTF-8, and that standard output is UTF-8 too (Well, the latter can be skipped but you'll get a warning):
In a one-liner, the -C command line options arguments controls what's considered UTF-8: D tells perl to use UTF-8 as the default encoding for PerlIO channels that are opened (For both read and write; there are other options for just reading or just writing; see perlrun for details), and S says that all standard streams (Input, output and error) are UTF-8 encoded.
So...
$ perl -CDS -wpe 's/\N{LATIN CAPITAL LETTER U WITH DIAERESIS}+/X/gu;' test.txt
A á X Ñ 日本語 1 1 / _

how to convert simple string cpp variable to MIPS code

Sounds simple, but I have been searching for a good hour or so now.
I want to know if there is a way for me to start a register with a string without having to store the string in .data.
For example, I can do; li $t0, 0 which has the effect of setting $t0 = 0. This is the same as me saying int a = 0 in cpp.
However, is there a similar way for me to convert std::string a = "Hello" to MIPS?
Currently I can do something like this
.data
mes: .asciiz "Hello" #declares 'mes' as "Hello"
.text
la $t0, mes #sets $t0 equals to the content of 'mes'
but I wish I could skip the first step by doing something like
sc $t0, "Hello" #set $t0 to characters "Hello" (note: this is not valid MIPS)
A string is nothing but a pointer to a byte/char that ends at 0 value byte.
Since there is no native c++ to MIPS compiler we could argue with common sense that the simplest way to define and initialize a string in MIPS is
.data
mes: .asciiz "Hello"
.text
la $t0, mes

Break anywhere when $r1 equals to a certain string in GDB

Is there anyway to break on gdb when $r1 equals to a certain string I know there is :
break [addr] if ((int)strcmp($r1, "hello")) == 0
But what to set in addr when I just wanna break when the r1 is "hello" no matter the current function/address?

In g+++ unable to print large string

The sendbyts prints all values when the string is smaller than 15 bytes . I verified the content with strtok and all details are present in the string. I am not able to output the whole string with cout<
for(i=0;i<=1;i++){
sendbyts= peerinfo[i].n_ip;
sendbyts.append(" ");
cout<< peerinfo[i].n_ip<<"\n";
//verify whether the right data is appended
sendbyts.append(peerinfo[i].n_portno);
sendbyts.append(" ");
cout<< peerinfo[i].n_portno<<"\n";
cout<<"verify the string here :"<<sendbyts<<"\n";
sendbyts.append("0x0");
sendbyts.append(" ");
cout<<" \n verify the string again :"<<sendbyts<<"\n";
sendbyts.append(peerinfo[i].n_sno);
sendbyts.append(" ");
cout<<peerinfo[i].n_sno<<"\n";
sendbyts.append("|");
cout<<" \n final verification :"<<sendbyts<<"\n";
}
cout<<"final string formed "<<sendbyts<<"\n";
output
128.205.36.8
6666
erify the string here :128.205.36.8 6666
0x0 fy the string again :128.205.36.8 6666
0x0 1 |erification 128.205.36.8 6666
Expected output
128.205.36.8
6666
verify the string here :128.205.36.8 6666128.205.36.8 6666
verify the string again :128.205.36.8 6666 0x0
final verification :128.205.36.8 6666 0x0 1|
You output looks like it's printing a carriage return ('\r') without a newline. When this happens, the cursor goes back to the start of the line without moving down. The subsequent text is printed over the last text.
Try changing any '\r' characters to '\n' characters.