MIPS float printing - double

I wrote this code in MIPS to calculate the sum of N-numbers with double float precision.
But when I print the result it prints 0.00000 althought I see that in memory it's the correct result.
Anyone can help me with this?
#architecture ex.2
.data
first: .asciiz "Give the number of the summation"
m1: .asciiz "Give the"
m2: .asciiz "th number."
nl: .asciiz "\n"
final: .asciiz "The sum is"
.text
main:
li $v0, 4
la $a0, first
syscall
li $v0,5
syscall
move $t1,$v0
li $v0, 4
la $a0, nl
syscall
li $t2,0
li $t0,1
mtc1.d $t2, $f2
cvt.d.w $f2, $f2
Sumin:
li $t3,0
li $v0, 4
la $a0, m1
syscall
li $v0,1
move $a0,$t0
syscall
li $v0, 4
la $a0, m2
syscall
li $v0, 4
la $a0, nl
syscall
li $v0,5
syscall
move $t3,$v0
mtc1.d $t3, $f14
cvt.d.w $f14, $f14
add.d $f2,$f2,$f14
addi $t0,$t0,1
ble $t0,$t1,Sumin
Sumexit:
li $v0, 4
la $a0, final
syscall
li $v0, 4
la $a0, nl
syscall
li $v0,2
mov.d $f12,$f2
syscall
END:jr $ra

I'd just suggest printing the double in $f12, not just the float
li $v0, 3
mov.d $f12, $f2
syscall

Related

MIPS Assembly convert integer to ascii string using memory

Hi i have a problem with my subroutine code. here is my code. It's giving a
Runtime exception at 0x00400074: address out of range 0x000000c8 error.
The line is: sb $t2, 0($t4) - It's the second store byte.
intToa: addi $sp, $sp, -12
sw $ra ,8($sp)
sw $a0, 4($sp)
sw $a1, 0($sp)
move $t0, $a0
move $t4, $a1
bne $t0, $zero, while
li $t2, 48
sb $t2, 0($t4)
addi $t4, $t4, 1
b end
while: beq $t0, $zero, end
li $t6, 10
div $t0, $t6 # divide $t0 by 10
mfhi $t1 # $t3 = $t0%10 (last digit of $t0)
mflo $t0 # $t0 = $t0/10 (first digit of $t0)
addi $t2, $t1, 48 # store character '0' to $t1 in
sb $t2, 0($t4) # out destinationg string
addi $t4, $t4, 1 # increment our string pointer
j while # continue looping
end:
sb $zero, 0($t4) # null terminate our string
move $a1, $a0
jal reverse
lw $ra, 12($sp)
addiu $sp, $sp, 12 # put stack back in place
jr $ra

How to print same row data in multiple time from pdb file in perl

I am new in perl, I ma trying to write a program to input pdb file (from Directory, I have 3000 files) and output will save another directory (Another folder).
Code:
open( filehandler, "Document1.txt" ) or die $!; #Input file
my #file1 = <filehandler>;
my $OutputDir = 'C:\test_result_file';
foreach my $line (#file1) {
chomp $line;
open( fh, "$line" ) or die $!;
open( out, ">$OutputDir/$line.pdb" ) or die $!;
while ( $file = <fh> ) {
if ( $file =~ /^ATOM.{9}(?:CG|CD1|CD2B|CE1|CE2|CZ|C|O|CB|CG|CD)/ ) {
$hash{$1}{$2}++;
}
foreach $key ( sort { $hash{$1} <=> $hash{$2} or $1 cmp $2 } keys %hash ) {
print out $key;
}
}
print "Completed", "\n";
}
for example input file:
ATOM 1752 CG TYR A 248 89.088 39.843 51.944 1.00 32.03 C
ATOM 1753 CD1 TYR A 248 89.759 39.356 50.810 1.00 37.15 C
ATOM 1754 CD2 TYR A 248 87.727 40.049 51.864 1.00 32.81 C
ATOM 1755 CE1 TYR A 248 89.078 39.081 49.646 1.00 36.00 C
ATOM 1756 CE2 TYR A 248 87.035 39.774 50.706 1.00 35.66 C
ATOM 1757 CZ TYR A 248 87.708 39.285 49.599 1.00 35.16 C
ATOM 7394 C GLN B 331 37.664 74.934 36.854 1.00 22.75 C
ATOM 7395 O GLN B 331 37.728 73.730 36.607 1.00 31.73 O
ATOM 7396 CB GLN B 331 37.467 76.222 34.712 1.00 27.88 C
ATOM 7397 CG GLN B 331 36.515 76.825 33.693 1.00 32.42 C
ATOM 7398 CD GLN B 331 35.390 75.877 33.328 1.00 35.70 C
Expected output:
A chain:
ATOM 1753 CD1 TYR A 248 89.759 39.356 50.810 1.00 37.15 C
ATOM 1752 CG TYR A 248 89.088 39.843 51.944 1.00 32.03 C
ATOM 1754 CD2 TYR A 248 87.727 40.049 51.864 1.00 32.81 C
ATOM 1755 CE1 TYR A 248 89.078 39.081 49.646 1.00 36.00 C
ATOM 1753 CD1 TYR A 248 89.759 39.356 50.810 1.00 37.15 C
ATOM 1754 CD2 TYR A 248 87.727 40.049 51.864 1.00 32.81 C
ATOM 1755 CE1 TYR A 248 89.078 39.081 49.646 1.00 36.00 C
ATOM 1756 CE2 TYR A 248 87.035 39.774 50.706 1.00 35.66 C
ATOM 1754 CD2 TYR A 248 87.727 40.049 51.864 1.00 32.81 C
ATOM 1755 CE1 TYR A 248 89.078 39.081 49.646 1.00 36.00 C
ATOM 1756 CE2 TYR A 248 87.035 39.774 50.706 1.00 35.66 C
ATOM 1757 CZ TYR A 248 87.708 39.285 49.599 1.00 35.16 C
B chain:
ATOM 7394 C GLN B 331 37.664 74.934 36.854 1.00 22.75 C
ATOM 7395 O GLN B 331 37.728 73.730 36.607 1.00 31.73 O
ATOM 7396 CB GLN B 331 37.467 76.222 34.712 1.00 27.88 C
ATOM 7397 CG GLN B 331 36.515 76.825 33.693 1.00 32.42 C
ATOM 7395 O GLN B 331 37.728 73.730 36.607 1.00 31.73 O
ATOM 7396 CB GLN B 331 37.467 76.222 34.712 1.00 27.88 C
ATOM 7397 CG GLN B 331 36.515 76.825 33.693 1.00 32.42 C
ATOM 7398 CD GLN B 331 35.390 75.877 33.328 1.00 35.70 C
ATOM 7396 CB GLN B 331 37.467 76.222 34.712 1.00 27.88 C
ATOM 7397 CG GLN B 331 36.515 76.825 33.693 1.00 32.42 C
ATOM 7398 CD GLN B 331 35.390 75.877 33.328 1.00 35.70 C
ATOM 7394 C GLN B 331 37.664 74.934 36.854 1.00 22.75 C
Chain ID may be a to h. so, rule is see above expected output: First four row will unique and then line five will be same row of second row and will add new row as eight line row.
I am unable to write a code to solve this problem, any one pl help
I'm afraid I have to say your code is rather confusing but what I get from the data samples and further explanation is:
There should be a window of four lines moving through the input lines.
The window contents (all four lines) should be printed as you advance to each new line.
The window should be reset each time a new sequence is encountered.
Each line is a series of space delimited fields and the fifth field identifies the sequence.
The window contents can be stored in a simple Perl array (see #window in the snippet below). You simply append data to it with push and remove the first line with shift as you move to a next line. When the sequence changes, print the current window and reset it. In the sample code below I made an assumption that sequences do not intermix. If this is note the case, you need to read all the input beforehand and sort it as necessary.
use strict;
use warnings;
my $win_len = 4;
my #window = ();
my $prev_chain = "";
while (<>) {
my ($atom_name, $chain) = (split)[2, 4];
next unless $atom_name =~ /\b(?:CG|CD1|CD2B|CE1|CE2|CZ|C|O|CB|CG|CD)\b/;
if ($chain eq $prev_chain) {
if (#window == $win_len) {
print_window();
shift #window;
}
push #window, $_;
} else {
print_window() if #window;
#window = ($_);
$prev_chain = $chain;
}
}
print_window() if #window;
sub print_window {
print foreach #window;
print "\n";
}
Demo: https://ideone.com/oOB8bF
The script reads data from STDIN and prints result to STDOUT for the sake of simplicity. Your code sample suggests you store a list of files to process in the Document1.txt and the actual input is read from these files. In this case you need an extra loop:
use strict;
use warnings;
my $OutputDir = 'C:/test_result_file';
open my $dir, "Document1.txt" or die "Failed to open Document1.txt:$!";
chomp(my #files = <$dir>);
foreach my $file (#files) {
my $win_len = 4;
my #window = ();
my $prev_chain = "";
open my $input, $file or die "failed to open $file: $!\n";
open my $output, '>', "$OutputDir/$file.pdb" or die "failed to open $OutputDir/$file.pdb: $!\n";
while (<$input>) {
my ($atom_name, $chain) = (split)[2, 4];
next unless $atom_name =~ /\b(?:CG|CD1|CD2B|CE1|CE2|CZ|C|O|CB|CG|CD)\b/;
if ($chain eq $prev_chain) {
if (#window == $win_len) {
print_window($output, #window);
shift #window;
}
push #window, $_;
} else {
print_window($output, #window) if #window;
#window = ($_);
$prev_chain = $chain;
}
}
print_window($output, #window) if #window;
}
sub print_window {
my $fh = shift;
print $fh $_ foreach #_;
print $fh "\n";
}

Mips Assembly. Connect, read, and write

My objective is to open a socket, connect to that socket on a port, and then whenever that socket sends data to me, I want to write it to stdout.
My code works fine, but for some reason the string that is writing doesn't null terminate? I'm not so sure what the issue is and I have yet to find anything online about it.
#socket(2,1,0)
li $t7, -6
nor $t7, $t7, $zero
addi $a0, $t7, -3
addi $a1, $t7, -3
slti $a2, $zero, -1
li $v0, 4183
syscall 0x40404
sw $v0, -4($sp)
#connect(3, &addr, 16)
lw $a0, -4($sp)
li $t7, -3
nor $t7, $t7, $zero
sw $t7,-32($sp)
lui $t6,0x7a69
ori $t6,$t6,0x7a69
sw $t6, -28($sp)
lui $t5, 0x7F00
ori $t5, $t5, 0x1
sw $t5, -26($sp)
addiu $a1, $sp, -30
li $t4, -17
nor $a2, $t4, $zero
li $v0, 4170
syscall 0x40404
#read(3, addr, 50)
nex:
lw $a0, -4($sp)
addiu $a1, $sp,-64
li $a2, 50
addi $a2, $a2, -1
li $v0, 4003
syscall 0x40404
beqz $a3, next
move $a2,$v0
negu $a2,$v0
next:
blez $a2,nextt
#write(1, addr, 50)
li $a0, 1
li $v0, 4004
syscall 0x40404
j nex
nextt:
Here is the strace of me writing a\n to the socket, and it writing a\n\0\0\0\0\0\0\0\0 to stdout.
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
connect(3, {sa_family=AF_INET, sin_port=htons(31337), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
read(3, "a\n", 49) = 2
write(1, "a\n\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 49a
zi3▒ݤ) = 49
As you can see, it prints out some weird characters at the end. Thanks for any help!
Notice in your strace output that your read syscall returns a value of 2 [in $v0].
Also notice that your write syscall has a length much greater than 2.
After your read syscall you have:
move $a2,$v0 # this reg has 2
negu $a2,$v0 # BUG: this changes it to -2 (0xFFFFFFFE)
The length for the write was interpreted as an unsigned number [and a very large one]
Change this to just [i.e. remove the negu]:
move $a2,$v0

beq command not jumping to a label in MIPS

I am creating a MIPS code in MARS that allows only an input of a numerical expression, and print an error message when characters other than numbers, +,-,*, and / are present.
In my following code, I set $s0 to zero if there is an invalid character, otherwise it stays at 1. If it is equal to zero, using the beq command I would jump to "erroneous" which handles the error message.
However, that last part does not seem to happen. If you run my code you'll see that it actually gets the proper values of $s0 right (that is, if the expression is invalid, it becomes equal to 0).
I need a fresh set of eyes, I would appreciate any help. Thanks!
.data
input: .space 102
trial: .asciiz "LOLLOL\n"
errormsg: .asciiz "ERROR\n"
.text
main:
addi $v0, $zero, 8
la $a0, input
addi $a1, $a0, 102
syscall
addi $t1 , $zero, 0
add $s1, $zero, $zero
addi $a0, $zero, -1
addi $s0, $zero,1
check_invalid_char_1:
#beq $s0, $s1, erroneous
jal check_invalid_char
j allowed
check_invalid_char:
addi $sp,$sp,-8
sw $ra, 0($sp)
sw $a0, 4($sp)
#sw $v0, 8($sp)
addi $a0, $a0,1
addi $t3, $zero,0
beq $s0, $zero, erroneous
lb $t2, input($a0)
beq $t2, 48, check_invalid_char_1 #pwede 0
beq $t2, 49, check_invalid_char_1 #pwede 1
beq $t2, 50, check_invalid_char_1 #pwede 2
beq $t2, 51, check_invalid_char_1 #pwede 3
beq $t2, 52, check_invalid_char_1 #pwede 4
beq $t2, 53, check_invalid_char_1 #pwede 5
beq $t2, 54, check_invalid_char_1 #pwede 6
beq $t2, 55, check_invalid_char_1 #pwede 7
beq $t2, 56, check_invalid_char_1 #pwede 8
beq $t2, 57, check_invalid_char_1 #pwede 9
beq $t2, 43, check_invalid_char_1 #pwede +
beq $t2, 45, check_invalid_char_1 #pwede -
beq $t2, 42, check_invalid_char_1 #pwede *
beq $t2, 47, check_invalid_char_1 #pwede /
beq $t2, 0, allowed #pwede null terminator
beq $t2, 10, allowed #pwede newline
add $s0, $zero,$zero
lw $ra, 0($sp)
lw $a0, 4($sp)
#lw $v0, 8($sp)
addi $sp, $sp, 8
jr $ra
erroneous:
#add $a0, $zero, $zero
la $a0, errormsg
addi $v0, $zero, 4
syscall
allowed:
addi $v0, $zero, 1
add $a0, $s0, $zero
syscall
#la $a0, errormsg
#addi $v0, $zero, 4
#syscall
addi $v0, $zero, 10
syscall
To anyone who may encounter this question, I may have solved my own problem, but I am not sure if it is really a fix, or a "cheat". It's more of a work around really.
I moved the "beq $s0, $zero, erroneous" line to the "allowed:" label. I don't know why it doesn't work from inside check_valid_char, but it works.
Then inside erroneous, I reset $s0 to 0 by using "sub $s0, $s0, $s0" so that when the code goes again to allowed: , beq will just be skipped and it will end normally.
If others can find a "real" solution for my problem, please post that.
Thanks!
edit: some punctuations.

MIPS - IEEE binary64 (double) and signed integer multiplication

I have a problem with MIPS project. The task is to multiply binary64(double) number by a signed integer without using floating-point Unit. It is almost working well, but for some numbers an error occurs(ex. float-123456789123456, int - 1). By error I mean that after 7th digit my result seems to differ from the proper one. I suspect there can be a problem with transfer of some bit during the procedure(maybe in process of adding $high of mantissa2 and $low of mantissa2). I tried to correct it, but so far I have no idea how to do it. Please verify my code and correct it if possible.
.data
text1: .asciiz "Enter double: "
text2: .asciiz "Enter integer: "
text3: .asciiz "Result: "
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: "
num1a: .word 0 #multiplicand and result(sign exponent and first part of mantissa)
num1b: .word 0 #second part of the multiplicand and result(remaining part of mantissa)
num2: .word 0 #integer
.text
.globl input
input:
#print "Enter double: "
la $a0, text1
li $v0, 4
syscall
# saving input double into num1
li $v0, 7
syscall
swc1 $f0, num1b
swc1 $f1, num1a
#print "Enter integer: "
la $a0, text2
li $v0, 4
syscall
# saving input int into num2
li $v0, 5
syscall
sw $v0, num2
# loading data to registers
lw $t0, num1a
lw $t1, num1b
lw $t2, num2
#########################################################sign
sign:
move $t3, $t0
andi $t3, $t3, 0x80000000 #preserve sign, zero the rest
bgez $t2, extract #if less than zero we change the final sign and negate the value of integer
xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0)
neg $t2, $t2 #absolute value of int
extract:
################################################checking for zero
or $t5, $t0, $t1 #if both part of double are equal to zero we skip all the calculation
beqz $t5, result_zero
beqz $t2, result_zero
###############################sign, exponent and mantissa
move $t7, $t0
andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7
move $t8, $t0
andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa
ori $t8, $t8, 0x00100000 #adding prefix one to mantissa
#remaining mantissa stays in register $t1
#########################################################
multiply:
########################multiplying mantissa part 1
multu $t8, $t2 #multiply mantissa1 by integer
mflo $t8 #low part of multiplication to $t8
mfhi $s1 #high part of multiplication to $s1
########################multiplying mantissa part 2
multu $t1, $t2 #mantissa part 2 multiplication
mflo $t1 #low part to $t1
mfhi $t0 #with overflow going to $t0
########################partial accumulation
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
shift: #else we shift 3 parts of mantissa and increment the the exponent
###extracting least significant bit of high mantissa1
sll $s2, $s1, 31 #copying least significant beat of $s1 to most significant bit in $s2
sll $t9, $t8, 31 #copying least significant beat of $s8 to most significant bit in $t9
######
srl $s1, $s1, 1 #shifting right mantisa part1 high
srl $t8, $t8, 1 #shifting right mantisa part1 low
or $t8, $t8, $s2 #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low
srl $t1, $t1, 1 #shifting right mantisa part2
or $t1, $t1, $t9 #copying least significant bit from mantissa1 to most significant bit of mantissa2
######
addiu $t7, $t7, 0x00100000 #increment exponent by one
######
bnez $s1, shift #if mantissa1 high is greater than zero we continue
bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space
result:
andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one)
move $t0, $t3 #copy propoer sign
or $t0, $t0, $t7 #add exponent
or $t0, $t0, $t8 #add mantissa part1
b output
result_zero:
li $t0, 0
li $t1, 0
output:
sw $t0, num1a
sw $t1, num1b
#print "Result: "
la $a0, text3
li $v0, 4
syscall
lwc1 $f12, num1b
lwc1 $f13, num1a
#print double - the result
li $v0, 3
syscall
question:
la $a0, quest #Do you want to enter new numbers or finish?
li $v0, 4
syscall
li $v0, 5 #reads the answer (integer)
syscall
beq $v0, 1, input #if input =1, continue, if 0 finish, otherwise ask again
beqz $v0, fin
b question
fin:
li $v0, 10 #exit
syscall
I think the problem might be in this section(multiply):
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
#addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
The process of adding may cause a carry out. I tried to handle it with instruction held in comment (addiu).It means that if the result of adding two unsigned numbers is less than one of them we obtain a cary out and have to add 1 to register $s1 which holds the most significant part of mantissa.It didn't help.
In my opinion this is the correct code:
.data
text1: .asciiz "Enter double: "
text2: .asciiz "Enter integer: "
text3: .asciiz "Result: "
quest: .asciiz "\nIf you want to multiply enter 1, otherwise enter 0: "
num1a: .word 0 #multiplicand and result(sign exponent and first part of mantissa)
num1b: .word 0 #second part of the multiplicand and result(remaining part of mantissa)
num2: .word 0 #integer
.text
.globl input
input:
#print "Enter double: "
la $a0, text1
li $v0, 4
syscall
# saving input double into num1
li $v0, 7
syscall
swc1 $f0, num1b
swc1 $f1, num1a
#print "Enter integer: "
la $a0, text2
li $v0, 4
syscall
# saving input int into num2
li $v0, 5
syscall
sw $v0, num2
# loading data to registers
lw $t0, num1a
lw $t1, num1b
lw $t2, num2
#########################################################sign
sign:
move $t3, $t0
andi $t3, $t3, 0x80000000 #preserve sign, zero the rest
bgez $t2, extract #if less than zero we change the final sign and negate the value of integer
xori $t3, $t3, 0x80000000 #multiply signs (if integer is negative, then the sign is equal to $s0)
neg $t2, $t2 #absolute value of int
extract:
################################################checking for zero
or $t5, $t0, $t1 #if both part of double are equal to zero we skip all the calculation
beqz $t5, result_zero
beqz $t2, result_zero
###############################sign, exponent and mantissa
move $t7, $t0
andi $t7, $t7, 0x7FF00000 #extracting exponent to $t7
move $t8, $t0
andi $t8, $t8, 0x000FFFFF #extracting first part of mantissa
ori $t8, $t8, 0x00100000 #adding prefix one to mantissa
#remaining mantissa stays in register $t1
#########################################################
multiply:
########################multiplying mantissa part 1
multu $t8, $t2 #multiply mantissa1 by integer
mflo $t8 #low part of multiplication to $t8
mfhi $s1 #high part of multiplication to $s1
########################multiplying mantissa part 2
multu $t1, $t2 #mantissa part 2 multiplication
mflo $t1 #low part to $t1
mfhi $t0 #with overflow going to $t0
########################partial accumulation
addu $t8, $t8, $t0 #adding the high part of mantissa2 to result of low part of mantissa1
bgeu $t8, $t0, skip_add #if the result is less than any element we add 1 to mantissa1 high
addiu $s1, $s1, 1
######
skip_add:
bnez $s1, shift
bltu $t8, 0x00200000, result
shift: #else we shift 3 parts of mantissa and increment the the exponent
###extracting least significant bit of high mantissa1
sll $s2, $s1, 31 #copying least significant beat of $s1 to most significant bit in $s2
sll $t9, $t8, 31 #copying least significant beat of $s8 to most significant bit in $t9
######
srl $s1, $s1, 1 #shifting right mantisa part1 high
srl $t8, $t8, 1 #shifting right mantisa part1 low
or $t8, $t8, $s2 #copying least significant bit from mantissa1- high to most significant bit of mantissa1 low
srl $t1, $t1, 1 #shifting right mantisa part2
or $t1, $t1, $t9 #copying least significant bit from mantissa1 to most significant bit of mantissa2
######
addiu $t7, $t7, 0x00100000 #increment exponent by one
######
bnez $s1, shift #if mantissa1 high is greater than zero we continue
bgeu $t8, 0x00200000, shift #if mantissa1 low exceeds final mantissa space
result:
andi $t8, $t8, 0x000FFFFF #preserve mantissa, zero the rest(cut the prefix - one)
move $t0, $t3 #copy propoer sign
or $t0, $t0, $t7 #add exponent
or $t0, $t0, $t8 #add mantissa part1
b output
result_zero:
li $t0, 0
li $t1, 0
output:
sw $t0, num1a
sw $t1, num1b
#print "Result: "
la $a0, text3
li $v0, 4
syscall
lwc1 $f12, num1b
lwc1 $f13, num1a
#print double - the result
li $v0, 3
syscall
question:
la $a0, quest #Do you want to enter new numbers or finish?
li $v0, 4
syscall
li $v0, 5 #reads the answer (integer)
syscall
beq $v0, 1, input #if input =1, continue, if 0 finish, otherwise ask again
beqz $v0, fin
b question
fin:
li $v0, 10 #exit
syscall