math.haifa.ac.ilmath.haifa.ac.il/.../CompArch/lectures/lecture6/CArch12.docx · Web...

Preview:

Citation preview

מספרים ממשיים mips תוכנית דוגמא לתוכנית

מספרים ממשיים2 המקבלת mipsלהלן תוכנית באסמבלי של ה-מהמשתמש ומדפיסה את סכומם.

המשתמש חייב להכניס אתת המספרים בפורמט:

[ - / +] x.xxxxxe(- +)ddd

או

[ - / +] x.xxxxxE(- +)ddd

–1.00כלומר +/- מובילים הם אופציונליים, מספר ממשי עשרוני מנורמל .0-308 חובה, סימן חזקה + - חובה, ומספר חזקה e/E, אות 9.9999

אסור רווחים או נקודה עשרונית במקום אחר.

לא חייבים את כל הספרות של החזקה.

דוגמאות:

6.754e-54,

+7.854e-65,

-8.91e-189,

9.765e+289,

-8.97E+167 …

התוכנית אינה בודקת נכונות קלט.

הפלט של התוכנית נראית ככה:

6.754-E-54 * -7.843E+87 = d.97162199e+34

5.5432e+34 * 6.785E+11 = 3.76106120e+46

6.754E-34 * 1.23456E+123 = 8.33821823e+89

4.321e-176 * 7.65e+59 = 3.30556500e-116

8.543e-49 * 9.876e-128 = 8.43706680e-176

5.64e+127 * 7.98e+98 = 4.50071999e+226

7.987e+279 * 4.84e+18 = 3.86570799e+298

3.6543e-167 * 6.876e+289 = 2.51269667e+123

לרוץ.הסימולטור איטי והתוכנית יכולה לקחת מספר שניות

יכולות לשמש בסיס לתוכניות אחרות.myatof ו-myftoaהרוטינות

הבאה:C של התוכנית mipsהתוכנית היא תרגום לאסמבלי של ה-

// ftoa3a.c

#include <stdio.h> #include <stdlib.h> #include <string.h>

double dconsts[21] = {1.0E+100, 1.0E+200, 1.0E+300, 1.0E+10, 1.0E+20, 1.0E+30, 1.0E+40, 1.0E+50, 1.0E+60, 1.0E+70, 1.0E+80, 1.0E+90, 1.0E+1, 1.0E+2, 1.0E+3, 1.0E+4, 1.0E+5, 1.0E+6, 1.0E+7, 1.0E+8, 1.0E+9};

char MyZero[16] = "0.0000000e+00";

void myftoa(double f, char str[]){ int pos = 0; int pos1; int e=0, e1; double g; int i, digit, len;

if (f == 0.0) strcpy(str,MyZero); if (f < 0) {

f = -f; str[0] = '-'; pos++; } // if

if ( f < 1.0)

goto LessOne;

// f >= 1.0i=0;while( (f >= dconsts[i]) && (i < 3) ){ i++; e += 100;} // while

if ( i> 0)f = f / dconsts[i-1];

i=3;while( (f >= dconsts[i]) && (i < 12) ){ i++; e += 10;} // while//e += ((i-3)*10);

if ( i> 3)f = f / dconsts[i-1];

i=12;while( (f >= dconsts[i]) && (i < 21) ) { i++; e++; } //while

//e += (i-12);

if ( i> 12)f = f / dconsts[i-1];

goto GrOne;

/* while( f < 1.0) { e--; f = f *10.0; } // while*/

LessOne:

i=0;e = 0;while( ((f*dconsts[i]) < 1.0) && (i < 3) ){ i++; e -= 100;} // while//e -= (i*100);

if ( i> 0)f = f * dconsts[i-1];

i=3;while( ((f*dconsts[i]) < 1.0) && (i < 12) ){ i++; e -= 10;} // while//e -= ((i-3)*10);

if ( i> 3)f = f * dconsts[i-1];

i=12;while( ((f *dconsts[i])< 1.0) && (i < 21) ){ i++; e--;} // while//e -= (i-12);e--;

if ( i> 12)f = f * dconsts[i-1];

f = f * 10.0;

GrOne:

str[pos+1] = '.'; pos1 = pos + 1; for(i=0; i < 8; i++) { g = 1.0; digit = 0; while(g < f) { digit++; g = g + 1.0; } // while str[pos++] = digit + '0'; if(pos == pos1) pos++; f = f + 1.0 - g; f = f * 10.0; } // for

str[pos++] = 'e'; if (e < 0) { str[pos++] = '-'; e = -e; } else str[pos++] = '+';

e1 = e; len = 0; do { len++; e1 = e1 / 10; } while(e1 > 0);

len--;

str[pos+len+1]= '\0'; do { digit = e % 10; e = e / 10; str[pos+len]= digit + '0'; len--; } while(e > 0); } // myftoa

double myatof(char str[], int n){ int i, j, digit,k, k1, sign; double f, g, pow10, fsign;;

i = 0; if(str[0] == '-') { fsign = -1; i++; } // if else { fsign = 1; if(str[0] == '+') i++; } // else pow10 = 0.1; digit = str[i] - '0'; f = digit; i += 2; while( (str[i]!= 'e') && (str[i]!= 'E') ) { digit = str[i] - '0'; g = digit * pow10; f = f + g; pow10 = pow10*0.1; i++; } // while

i++; pow10 = 10.0; k = 0;

if (str[i] == '-') sign = -1; else sign = 1; i++; while(i < n) { k = k * 10; k = k + (str[i] - '0'); i++; } // while

if (sign == 1){ k1 = k / 100;if (k1 != 0) f = f * dconsts[k1-1]; k1 = (k - k1*100)/10;if (k1 != 0) f = f * dconsts[k1+2]; k1 = k % 10;if (k1 != 0) f = f * dconsts[k1+11]; } // ifelse{ k1 = k / 100;if (k1 != 0) f = f / dconsts[k1-1]; k1 = (k - k1*100)/10;if (k1 != 0) f = f / dconsts[k1+2]; k1 = k % 10;if (k1 != 0) f = f / dconsts[k1+11]; } // if

return (fsign*f);} // myatof

int main(int argc, char *argv[]){ double f,g, h;

char str[80];if (argc < 3) { fprintf(stderr, "usage: myftoa double\n"); exit(0); } // if

f = myatof(argv[1], strlen(argv[1]));g = myatof(argv[2], strlen(argv[2]));h = f*g;myftoa(h, str);printf("%s * %s = %s\n",argv[1], argv[2], str);return 0;

} // main

התוכנית מקבלת מספרים כפרמטר לתוכנית ראשית.

לדוגמא:

a.exe -5.876e+54 +7.987e-289-5.876e+54 * +7.987e-289 = -4.6931612e-234

:mipsתוכנית ה-

; dmult.asm - multiply two numbers from keyboard; Use functions.dataNum: prompt_msg1: .asciiz "Enter First number"prompt_msg2: .asciiz "Enter Second number"params_sys1: .word64 0param2: .word64 0param3:.word64 0x10

len1:.word64 0x10len2:.word64 0x10len3:.word64 0x10Number1_text: .space 32result_msg1: .asciiz " * "Number2_text: .space 32result_msg2: .asciiz " = "Number3_text: .space 32One: .word64 0x1Two: .word64 0x2 Three: .word64 0x3Ten: .word64 0xAHundred: .word64 100 C31: .word 0x1FDZero: .double 0.0DTen: .double 10.0DOne: .double 1.0Dconsts: .double 1.0E100 .double 1.0E200 .double 1.0E300 .double 1.0E10 .double 1.0E20 .double 1.0E30 .double 1.0E40 .double 1.0E50 .double 1.0E60 .double 1.0E70 .double 1.0E80 .double 1.0E90 .double 1.0E1 .double 1.0E2

.double 1.0E3 .double 1.0E4 .double 1.0E5 .double 1.0E6 .double 1.0E7 .double 1.0E8 .double 1.0E9MyZero: .asciiz "0.00000000e+0"

ZeroCode: .word64 0x30 ; Ascii '0' .textmain: ; r14 points to pramaters for syscalldaddi r8, r0,Number1_text ; r8 = Number1_textdaddi r14, r0, params_sys1 ; r14 = &params_sys1daddi r9,r0,32 jal read_keyboard_inputsd r1,len1(r0) ; Save first number lengthread2: daddi r14, r0, params_sys1daddi r8, r0,Number2_textdaddi r9,r0,32 jal read_keyboard_input;sd r1,len2(r0) ; Save first number lengthld r10,len1(r0) ; n = r10 = length of Number1_textdaddi r17,r0,Number1_textjal myatof;mov.d f13,f11 ; f12 = f11 = x1;daddi r17,r0,Number2_textld r10,len2(r0) ; n =r10 = length of Number2_textjal myatof; mul.d f12,f13,f11; f12 = x1 * x2 mov.d f11,f12;daddi r17,r0,Number3_text ; r17 = &Number3_text jal myftoasd r18,len3(r0) ; len3 = toString(r11) length;; Set up SYSCALL 4 write to screen

daddi r8, r0, Number1_text ; r9 = offset Number1_textld r9,len1(r0) ; Third paramjal print_string;daddi r8, r0, result_msg1 ;r22 = offset result_msg1 ld r9,Three(r0) ; Third paramjal print_string;daddi r8, r0, Number2_textld r9,len2(r0) ; Third paramjal print_string;daddi r8, r0, result_msg2ld r9,Three(r0) ; Third paramjal print_string;daddi r8, r0, Number3_textld r9,len3(r0) ; Third param jal print_string

end:syscall 0

read_keyboard_input:; function, expects r14 =&parameter address, r8 = &Destination string; r9 = max destination size; returns computed number in r11;sd r0,0(r14) ; read from keyboardsd r8,8(r14) ; Destinatiom addresssd r9,16(r14) ; Destination sizesyscall 3jr $ra

myatof:; function, expects r10 =string length, r17 = &Source string; returns computed number in f11

ldc1 f11,DZero(r0)ldc1 f10,DTen(r0)ldc1 f8,DOne(r0)ldc1 f0,DZero(r0)movz r9,r0,r0 ; r9 == i =0

movz r18,r17,r0 ; r18 = &str[0]movz r6,r0,r0lb r6,0(r18)daddi r7,r0,45; r7 = '-'bne r6,r7,Skipa1sub.d f8,f0,f8 ; f8 = -1;daddi r18,r18,1b Skipa2Skipa1:daddi r7,r0,43; r7 = '+'bne r6,r7,Skipa2daddi r18,r18,1Skipa2:ldc1 f22,DOne(r0)div.d f29,f22,f10 ; f22 = 0.1mov.d f22,f29movz r6,r0,r0lb r6,0(r18); r6 = str[i]daddi r6,r6,-48 ; r6 = r6 - '0'dmtc1 r6,f5cvt.d.l f5,f5 ; f5 = (double) (str[i] - '0')add.d f11,f11,f5daddi r18,r18,2Whilea1:daddi r7,r0,101 ; r7 = 'e'movz r6,r0,r0lb r6,0(r18); r6 = str[i]beq r6,r7,EndWhilea1 daddi r7,r0,69; r7 ='E'beq r6,r7,EndWhilea1 daddi r7,r0,48; r7 = '0'dsub r6,r6,r7 ; r6 = r6 - '0'dmtc1 r6,f5cvt.d.l f5,f5 ; f5 = (double) (str[i] - '0')mul.d f5,f5,f22add.d f11,f11,f5div.d f22,f22,f10daddi r18,r18,1b Whilea1EndWhilea1:

daddi r18,r18,1mov.d f22,f10movz r5,r0,r0

daddi r24,r0,1daddi r7,r0,45; r7 = '-'movz r6,r0,r0lb r6,0(r18); r6 = str[i]bne r6,r7,Skipa3daddi r24,r0,-1;daddi r18,r18,1Skipa3:;daddi r18,r18,1daddi r18,r18,1dsub r25,r18,r17 ; r25 = i;movz r19,r0,r0ld r20,Ten(r0)Whilea2: dsub r21,r25,r10 beqz r21,EndWhilea2 dmult r19,r20 mflo r19 movz r6,r0,r0 lb r6,0(r18); r6 = str[i] daddi r6,r6,-48 ; r6 = r6 - '0' dadd r19,r19,r6 daddi r18,r18,1 daddi r25,r25,1b Whilea2EndWhilea2: movz r29,r19,r0bgez r24,PositivePower

daddi r21,r0,8 ; r21 = 8addi r10,r0,100; r10 = 100ddiv r29,r10mflo r15movz r16,r15,r0beqz r16,NoHundred1addi r16,r16,-1dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)div.d f11,f11,f28NoHundred1:dmult r15,r10mflo r16dsub r16,r29,r16

addi r10,r0,10ddiv r16,r10mflo r15movz r16,r15,r0beqz r16,NoTen1addi r16,r16,2dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)div.d f11,f11,f28NoTen1:ddiv r29,r10mfhi r15movz r16,r15,r0beqz r16,NoOne1addi r16,r16,11dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)div.d f11,f11,f28

NoOne1:

b NoOne2

PositivePower:

daddi r21,r0,8addi r10,r0,100ddiv r29,r10mflo r15movz r16,r15,r0beqz r16,NoHundred2addi r16,r16,-1dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)mul.d f11,f11,f28NoHundred2:dmult r15,r10mflo r16dsub r16,r29,r16addi r10,r0,10

ddiv r16,r10mflo r15movz r16,r15,r0beqz r16,NoTen2addi r16,r16,2dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)mul.d f11,f11,f28NoTen2:ddiv r29,r10mfhi r15movz r16,r15,r0beqz r16,NoOne2addi r16,r16,11dmult r16,r21mflo r16ldc1 f28,Dconsts(r16)mul.d f11,f11,f28

NoOne2:

mul.d f11,f11,f8

jr $ra

myftoa:; function, expects f11 =source number, r17 = &destination string; returns length in r18;; id f == 0.0?

mov.d f12,f11 ; f12 = xldc1 f0,DZero(r0)c.eq.d 7,f12,f0 ; f == 0.0?bc1f 7,NotZero ; No, Skipmovz r18,r17,r0; r18 = &str[0]addi r9,r0,13addi r29,r0,MyZeroMemCpy: beqz r9,EndMemCpy lb r6,0(r29) sb r6,0(r18) addi r18,r18,1

addi r29,r29,1 addi r9,r9,-1 b MemCpyEndMemCpy: addi r18,r0,13 jr $raNotZero:

movz r18,r17,r0; r18 = &str[0]ldc1 f0,DZero(r0)ldc1 f1,DOne(r0)ldc1 f10,DTen(r0)c.lt.d 7,f11,f0 ; x < 0 ?bc1f 7,NonNeg; No, x >= 0.0sub.d f12,f0,f12; f12 = -x (|x|)daddi r6,r0,45 ; str[0] = '-'sb r6,0(r18);daddi r18,r18,1NonNeg:; f < 1.0c.lt.d 7,f11,f1 ; x < 1 ?bc1t 7,LessOne ; No, x >= 0.0

addi r3,r0,3movz r9,r0,r0 ; r9 = 0movz r4,r0,r0 ; r4 = 0addi r29,r0,DconstsWhilefh1:ldc1 f29,0(r29)c.lt.d 7,f12,f29bc1t 7,EndWhilefh1beqz r3,EndWhilefh1 addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,100b Whilefh1EndWhilefh1:

beqz r4,NoH1addi r29,r29,-8ldc1 f29,0(r29)div.d f12,f12,f29

NoH1:addi r29,r0,Dconstsaddi r29,r29,24addi r4,r0,0addi r3,r0,9

Whileft1:ldc1 f29,0(r29)c.lt.d 7,f12,f29bc1t 7,EndWhileft1beqz r3,EndWhileft1 addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,10b Whileft1EndWhileft1:

beqz r4,NoD1addi r29,r29,-8ldc1 f29,0(r29)div.d f12,f12,f29NoD1:addi r29,r0,Dconstsaddi r29,r29,96addi r4,r0,0addi r3,r0,9

Whilefs1:ldc1 f29,0(r29)c.lt.d 7,f12,f29bc1t 7,EndWhilefs1beqz r3,EndWhilefs1 addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,1b Whilefs1EndWhilefs1:

beqz r4,NoS1addi r29,r29,-8ldc1 f29,0(r29)div.d f12,f12,f29

NoS1:

b GrOneLessOne:ldc1 f1,DOne(r0) addi r3,r0,3movz r9,r0,r0 ; r9 = 0movz r4,r0,r0 ; r9 = 0addi r29,r0,DconstsWhilefh2:ldc1 f29,0(r29)mul.d f13,f12,f29c.lt.d 7,f13,f1bc1f 7,EndWhilefh2beqz r3,EndWhilefh2 addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,-100b Whilefh2EndWhilefh2:

beqz r4,NoH2addi r29,r29,-8ldc1 f29,0(r29)mul.d f12,f12,f29NoH2:addi r29,r0,Dconstsaddi r29,r29,24addi r4,r0,0addi r3,r0,9

Whileft2:ldc1 f29,0(r29)mul.d f13,f12,f29c.lt.d 7,f13,f1bc1f 7,EndWhileft2beqz r3,EndWhileft2addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,-10b Whileft2

EndWhileft2:

beqz r4,NoD2addi r29,r29,-8ldc1 f29,0(r29)mul.d f12,f12,f29NoD2:addi r29,r0,Dconstsaddi r29,r29,96addi r4,r0,0addi r3,r0,9

Whilefs2:ldc1 f29,0(r29)mul.d f13,f12,f29c.lt.d 7,f13,f1bc1f 7,EndWhilefs2beqz r3,EndWhilefs2 addi r4,r4,1addi r3,r3,-1addi r29,r29,8addi r9,r9,-1b Whilefs2EndWhilefs2:addi r9,r9,-1

beqz r4,NoS2addi r29,r29,-8ldc1 f29,0(r29)mul.d f12,f12,f29NoS2:

ldc1 f10,DTen(r0)mul.d f12,f12,f10ldc1 f1,DOne(r0)c.lt.d 7,f12,f1bc1f 7,GrOne mul.d f12,f12,f10 addi r9,r9,-1GrOne:ldc1 f10,DTen(r0)daddi r6,r0,46 ; str[i] = '.'sb r6,1(r18)daddi r19,r18,1 ;r19 == pos1

movz r21,r0,r0daddi r22,r0,8

mov.d f23,f1 ; f23 = 1.0 daddi r23,r0,0 ; r23 == digit = 1 whilef3a: c.eq.d 7,f23,f12 bc1t 7,Eq1 c.lt.d 7,f23,f12 ; f23 < f12? bc1f 7,EndWhilef3a ; No, breakEq1: daddi r23,r23,1 ; digit++ add.d f23,f23,f1 b whilef3a EndWhilef3a:

daddi r23,r23,48; r23 = r23 + '0' sb r23,0(r18) ; str[i] = digit addi r18,r18,2 add.d f12,f12,f1 sub.d f12,f12,f23 mul.d f12,f12,f10

Forf1: beq r21,r22,EndForf1 ; i < 8? mov.d f23,f1 ; f23 = 1.0 daddi r23,r0,0 ; r23 == digit = 1 whilef3: c.lt.d 7,f23,f12 ; f23 < f12? bc1f 7,EndWhilef3 ; No, break daddi r23,r23,1 ; digit++ add.d f23,f23,f1 b whilef3 EndWhilef3: daddi r23,r23,48; r23 = r23 + '0' sb r23,0(r18) ; str[i] = digit daddi r18,r18,1 add.d f12,f12,f1 sub.d f12,f12,f23 mul.d f12,f12,f10 addi r21,r21,1 b Forf1

EndForf1: daddi r23,r0,101; r23 = 'e' sb r23,0(r18) ; str[i] = 'e' daddi r18,r18,1 ; i++ bgez r9,Skipf2 ; is e > 0? beqz r9,Skipf2 ; is e == 0?;No e < 0 daddi r23,r0,45; r23 = '-' sb r23,0(r18) ; str[i] = '-' daddi r18,r18,1 ; i++ dsub r9,r0,r9 ; r9 = -r9 = |r9| b Skipf3 Skipf2: daddi r23,r0,43 ; r23 = '+' sb r23,0(r18) ; str[i] = '+' daddi r18,r18,1 ; i++Skipf3: movz r14,r9,r0 ; r14 = e daddi r15,r0,0 ld r10,Ten(r0)Whilef4: daddi r15,r15,1 ddiv r14,r10 mflo r14 beqz r14,EndWhilef4 b Whilef4EndWhilef4: daddi r15,r15,-1 dadd r15,r15,r18 movz r18,r15,r0 ; set up result movz r14,r9,r0 ; r14 = e ld r10,Ten(r0)Whilef5: ddiv r14,r10 mflo r14 mfhi r23 daddi r23,r23,48 ; r23 = r23 + '0' sb r23,0(r15) daddi r15,r15,-1 beqz r14,EndWhilef5 j Whilef5EndWhilef5: dsub r18,r18,r17 daddi r18,r18,2

jr $ra;;print_string:; function, expects r14 =&parameter address, r8 = &Source string; r9 = source size; daddi r23,r0,2sd r23,0(r14) ; Write to output screensd r8,8(r14) ; Source addresssd r9,16(r14) ; Source sizesyscall 4jr $ra

Recommended