检讨:
笔记里出现了几个错误,被zyc大佬指出了
写博客不要马虎
1 存储单元寻址{ 2 访问主存单元{ 3 lw $s1,8($a1) 4 sw $s1,8($a1) 5 lw rt,offset(rs) 源操作数为基址寻址 6 sw rt,offset(rs) 目标操作数为基址寻址 7 } 8 基址寻址:{基地址+位移量} 9 } 10 11 数组{ 12 { 13 cin>>h; 14 A[12]=A[8]+h; 15 翻译{ 16 li $v0,5 17 syscall 18 move $s2,$v0 19 #ori $s2,$v0,0这也是一种复制的方法,add也可以~ 20 lw $t0,32($s3) 假设数组A的基地址在s3中,现在把s3的第(4*8)位地址取出来 21 add $t0,$s2,$t0 22 sw $t0,48($s3) 23 } 24 } 25 { 26 int array[1024]; 27 translate: 28 .data 29 array: .space 4096 #load byte 30 #.word 1024也可以 31 } 32 { 33 int pof2[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768}; 34 translate: 35 pof2: .word 1,2,4,6,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768 36 } 37 { 38 数组元素的访问pointer!pointer!pointer! 39 la $a0,pof2 40 lw,$s0,8($a0) #访问了pof[3]=4;0,4,8 41 } 42 { 43 lui $s1,0x1234 44 ori $s1,$s1 45 addi $t0,$0,100 46 sw $t0,0($s1) 47 } 48 } 49 立即数寻址/寄存器寻址{addi/add $s0,$s1,5/$s2} 50 51 赋值{ 52 全局/static变量{ 53 .data 54 i .word 100 55 } 56 后有赋值{ 57 ###################### 58 .data 59 i: .space 4 60 ###################### 61 .text 62 la $t0,i 63 addi $t1,$0,100 64 sw $t1,0($t0) 65 ###################### 66 利用宏(li指令是宏指令) 67 li $t0,100 68 sw $t0,i 69 ###################### 70 } 71 { 72 语句:i=j; 73 { 74 ############1######## 75 设i,j分别为$s1,$s0 76 add $s1,$0,$s0 77 #####################???????????????????? 78 i为动态变量,地址为0x12345678 79 j被指派到寄存器$s1 80 lui $t0,0x1234 $s1<----0x12340000 81 ori $t0,$t0,0x5678 $s1<----0x12345678 82 lw $s1,0($t0) 83 #####################???????????????????? 84 i,j均为动态变量,地址分别为 85 0x12345678,0x87654320 86 lui $t0,0x1234 #取出来放到高位 87 ori $t0,$t0,0x5678 88 lw $t1,0($t0) 89 lui $t0,0x8765 90 ori $t0,0x4320 91 sw $t1,0($t0) 92 #####################???????????????????? 93 i,j均为自动变量,宏寻址 94 lw $t0,i 95 sw $t0,j 96 } 97 98 } 99 } 100 101 mult和div都是二元的,指令周期分别为32和38,它们宏指令为三元{ 102 1. mult $a1,$s1 103 mflo $v0 #存低32位 104 mfhi $v1 #存高32位 105 106 2. div $a1,$s1 107 mflo $v0 #存商 108 mfhi $v1 #存余数 109 "乘积高32位/乘积低32位/商/余数复制到寄存器$v0,$v1" 110 111 3. 加载地址宏指令: 112 la Rdest,address 113 4. 加载立即数宏指令: 114 li Rdest,imm 115 两者实现方法相同: 116 lui $at,imm #$at寄存器编号为1,给汇编程序留用,把address/imm加载到$at里面 117 ori Rdest,$at,imm # 118 5. move Rdest,Rsrc #也是那么回事 119 } 120 声明{ 121 Rdest:存放结果的寄存器 122 Rsrc:立即数或者寄存器名 123 (rt/rs):源操作数 124 rd:目的操作数 125 } 126 127 { neg Rdest,Rsrc (求补码) 128 翻译: 129 sub Rdest $0,Rsrc 130 } 131 132 { abs Rdest,Rsrc 133 翻译: 134 bgez Rsrc,skip 135 sub Rdest,$0,Rsrc 136 skip: 137 ...... 138 } 139 140 xor/or/and--->xori/andi/ori{ 141 add{ 142 andi $a1,$a1,0x8001 #0x8001=1000 0000 0000 0001 143 "将$a1寄存器中的最低有效字节中存放的一个ASCii码取出,放到寄存器$t1中" 144 addi $t1,$a0,0x007f #0x007f=0000 0000 0111 1111 145 } 146 xor{ 147 //清空and取反 148 xor $a1,$a1,$a1 149 xori $a1,$a1,0x0020 #第5位取反 150 判断两寄存器中符号是否相同: 151 xor $t0,$s0,$s1 152 bgez $t0,same_sign #充分严重怀疑考试要考这种!!!!!!! 153 } 154 not:{nor Rdest,Rsrc,$zero} 155 对于负奇数除以2的操作{ 156 sub $a0,$0,$a0 157 sra $a0,$a0,1 158 sub $a0,$0,$a0 159 } 160 161 循环移位宏指令,是用来干什么的呢?{ 162 rol Rd,Rs,Src2 # 循环左移 163 ror Rd,Rs,Src2 # 循环右移 164 来康康实现方法{ 165 rol: 166 srl $at,Rs,32-sa # 假设sa=1,则at=rs>>31;右移31位,也就是把最高1位给取出来了 167 sll Rd,Rs,sa # rd=rs<<1,左移1位,把最低1位空出来了 168 or Rd,Rd,$at #最高1位和最低1位合并,这里的1位指:sa=1 169 ror: 170 sll $a1,Rs,32-sa 171 sri Rd,Rs,sa 172 or Rd,Rd,$at 173 } 174 } 175 } 176 跳转part{ 177 blez $s6,QUIZ 小于等于0 178 beqz $s6,Quiz 等于0 179 bgez $s6,Quiz 大于等于0 180 } 181 统计字符串中字符数量{ 182 la $t2,str 183 xor $t1,$t1,$t1 #快乐的清空操作 184 nextCh: 185 lb $t0,($t2) #get a byte from the string 186 begz $t0,strEnd 187 addiu $t1,$t1,1 #计数器+1,cnt++ 188 addiu $t2,$t2,1 #$t2地址加1,移动1byte 189 j nextCh 190 } 191 192 sqrt函数的使用{ 193 翻译语句: 194 $s0=sqrt($a0*$a0+$a1*a1); 195 mult $a0,$a0 196 mflo $t0 #注意这里体会只低位 197 mult $a1,$a1 198 mflo $t1 199 add $a0,$t0,$t1 200 jal srt #call the square root function 201 move $s0,$v0 #result of sqr is returned in $v0(standard convention) 202 } 203 再翻译一个{ 204 $s0=(pi*$t8*t8)/2; 205 li $t0,314159 206 mult $t8,$t8 207 mflo $t1 208 mult $t1,$t0 209 mflo $s0 210 sra $s0,$s0,1 #shift right arithmetic instruction 211 } 212 213 溢出/取反/补码/物理储存方式{ 214 这个需要补充 215 |*****| 216 ///v\\\ 217 o-- ||| ||| --o 218 \\\v/// 219 || || 220 **+** 221 | | 222 }> }? 223 } 224 225 226 SET操作{ 227 (bool型)给目的寄存器赋值0或者1 228 slt < 229 seq == 230 sge >= 231 sle sleu <= 232 sne != 233 234 j target 无条件跳转 235 beq>>>>> 条件跳转 236 bne bgez bgtz blez bltz 237 { 238 举个栗子: 239 int c=a>3&&b>=5{ 240 ## a:$a0,b:$a1,c:$v0 ## 241 li $s0,3 242 li $s1,5 243 sgt $t0,$a0,$s0 #a>=3 244 sge $t1,$a1,$s1 #b>=5 245 and $t0,$t0,$s1 246 move $v0,$t0 247 } 248 } 249 } 250 251 对于syscal:{ 252 指令编号(服务号)放入:$v0 253 输入参数事先放入$a1,$a0 254 执行syscall 255 返回值在$v0中 256 1 print_int $a0 257 5 read_int $v0 258 2&6 float $2->f11 6->f0 259 3&7 double $3->f12 7->f0 260 4 print_string $a0为首地址,用它输出 261 8 read_string 262 i.字符串缓冲区(buffer)首地址在$a0中 263 ii.字符串缓冲区大小在$a1中 264 10 exit 265 11 print_char 266 12 read_char 267 我有意见! 268 我没意见le 269 } 270 271 char_io.s:{273 .data 274 msg: .asciiz "input a char" 275 .text 276 .globl main 277 .ent main 278 main: 279 li $v0,4 280 la $a0,msg 281 syscall 282 283 li $v0,12 284 syscall 285 move $a1,$v0 286 287 li $v0,11 288 li $a0,0x0a #woyouyijiannigecsl 289 syscall 290 291 move $a0,$a1 292 li $v0,11 293 syscall 294 295 li $v0,10 296 syscall 297 .end main300 } 301 302 while循环/for循环小练习:{ 303 while循环翻译:{ 304 v0=1; 305 while(a1<a1){ 306 t1=mem[a1]; 307 t2=mem[a2]; 308 if(t1!=t2)break; 309 a1++; 310 a2--; 311 } 312 v0=0; 313 return 0; 314 翻译:{ 315 li $v0,1 316 loop: 317 bgeu $a1,$a2,done 318 lb $t1,0($a1) 319 lb $t2,0($a2) 320 bne $t1,$t2,break 321 addi $a1,$a1,1 322 addi $a1,$a1,-1 323 b loop 324 break: 325 li $v0,1 326 } 327 } 328 for循环翻译{ 329 a0=0; 330 for(int t0=10;t0>0;t0--)a0+=t0; 331 翻译: 332 li $a0,1 333 li $t0,10 334 loop: 335 add $a0,$a0,$t0 336 addi $t0,$t0,-1 337 bgtz $t0,loop 338 } 339 340 switch语句翻译{ 341 s0=32 342 top:cout<<"input a value from 1 to 3"; 343 cin>>v0; 344 switch(v0){ 345 case(1){s0<<=1;break;} 346 case(2){s0<<=2;break;} 347 case(3){s0<<=3;break;} 348 defalt:goto top; 349 } 350 cout<<s0; 351 翻译: 352 .data 353 .align 2 #貌似是4字节对齐 354 ############################################################### 355 插播一个小知识: 356 alignment: 357 字节:占用一个内存单元 358 半字:占用相邻两个内存单元,地址必须为偶地址,末尾至少1个0 359 字:四个,末尾至少2个0 360 双字:八个,被8整除,末尾至少3个0 361 因为MIPS指令字规模是32bits定长,所以每次都要以字对齐的方式在内存中存放指令 362 所以要.align 2 363 "当一条指令已从内存取出并存放到指令寄存器(IR)中后,PC地址增量4" 364 ############################################################### 365 jumptable: .word top,case1,case2,case3 366 msg: .asciiz "\n\ninput a value from 1 to 3:" 367 .text 368 top: 369 li $v0,4 370 la $a0,msg 371 syscall 372 373 li $v0,5 374 syscall 375 376 blez $v0,top 377 li $t3,3 378 bgt $v0,$t3,top 379 ################################################################################################# 380 la $a1,jumptable #jumptable的首地址保存在$a1寄存器里面 381 sll $t0,$v0,2 #这个程序利用输入的字符在jumptable里面寻址,地址是4个byte一个单元的 382 #$t0是位移量,$a1是基地址 383 #compute word offset 384 add $t1,$a1,$t0 #$t1现在应该是一个在jumptable里的指针,那么也就是jumptable的基地址 385 lw $t2,0($t1) #$t2:load an address from jumptable 386 #访问主存单元寻址必须用lw Rt,offset(Rs) 387 jr $t2 #是你小伙计!!!!! 388 ################################################################################################ 389 case1: sll $s0,$s0,1 390 b output 391 case2: sll $s0,$s0,2 392 b output 393 case3: sll $s0,$s0,3 394 output: 395 li $v0,1 396 move $a0,$s0 397 syscall 398 } 399 400 basic:{ 401 寄存器 rigister 速度快,代价高,数量有限 402 内存:速度慢,容量大,G字节规模,代价低 403 高速缓冲储存器:cache 404 符号扩展:将符号位扩展为高位数字 405 二进制加法;不同符号只要不溢出可以直接相加 406 二进制减法:减数取负然后二进制加法 407 溢出检测: 408 符号不同:不可能溢出 409 符号相同:必须和操作数有相同的符号 410 否则溢出 411 ATTENTION:最高位进位不一定溢出,两个负数相加一定进位但不一定溢出 412 } 413 414 415 调用函数:{ 416 现在有个函数:计算string_len 417 入口参数:字符串起始地址在$a0中,字符串命名string 418 出口参数:字符串长度,放到$v0里面 419 调用: 420 la $a0,string 421 jal string_len 422 move $t0,$v0 调用完之后,$v0中就被存放了字符段长度,然后把它move一下 423 424 program:{ 425 .text 426 .globl main 427 .ent main 428 main: 429 jal ret #call a function way1 430 431 la $t0,ret #call a function way2 432 jalr $ra,$t0 433 434 li $v0,1 435 syscall 436 .end main 437 438 ret: 439 440 jr $ra 441 442 } 443 }
FIB:优化:尾递归
1 ########################################## 2 #HOMEWORK4:Fibonacci 3 #Rabbit array 4 #Editor:VScode 5 ########################################## 6 ########################################## 7 .data 8 msg1: .asciiz "Now you have 10 rabbits~\n" 9 msg2: .asciiz "the Fibonacci number of 10 is : " 10 msg3: .asciiz "\n" 11 ########################################### 12 .text 13 .globl main 14 main: 15 16 li $v0,4 17 la $a0,msg1 18 syscall 19 20 ##1 21 subi $sp,$sp,32 22 sw $ra,28($sp) 23 sw $fp,24($sp) 24 addiu $fp,$sp,28 25 ##2 26 27 li $t0,10 28 sw $t0,16($sp) 29 30 lw $a0,16($sp) #argument fib(n) 31 jal fib 32 move $t0,$v0 33 34 li $v0,4 35 la $a0,msg2 36 syscall 37 38 li $v0,1 39 move $a0,$t0 40 syscall 41 42 lw $ra,28($sp) 43 lw $fp,24($sp) 44 addiu $sp,$sp,32 45 46 li $v0,10 47 syscall 48 49 fib: 50 #if(n==1||n==0)return 1; 51 #else return tailfib(n,1,1); 52 addiu $sp,$sp,-24 53 sw $ra,20($sp) 54 sw $fp,16($sp) 55 addiu $fp,$sp,20 #set up a frame pointer 56 57 li $t0,1 58 sw $a0,4($fp) #save argument(n) fp4 saves n 59 60 move $v1,$a0 61 beqz $v1,then #if n==0 62 beq $v1,$t0,then #if n==1 63 64 lw $a0,4($fp) #load argument(n) 65 li $a1,1 #$a1 is pre1 66 move $s3,$a0 67 move $s1,$t0 68 move $s2,$t0 69 jal tailfib 70 j done 71 72 then: 73 74 li $v0,1 75 j done 76 77 done: 78 79 lw $ra,20($sp) 80 lw $fp,16($sp) 81 addiu $sp,$sp,24 82 jr $ra 83 .end fact 84 85 tailfib: 86 li $t1,2 87 beq $s3,$t1,then1 88 lw $v0,4($sp) 89 add $v0,$s1,$s2 90 move $s2,$s1 91 move $s1,$v0 92 sub $s3,$s3,1 93 sw $v0,4($sp) 94 j tailfib 95 96 then1: 97 lw $v0,4($sp) 98 jr $ra 99 100 101 ###########EOF############################
1 #homework6: 2 # int tak(int x,int y,int z){ 3 # x<=y?:z:tak(tak(x-1,y,z),tak(y-1,z,x),tak(z-1,x,y)); 4 # } 5 #editor:VScode 6 ####################################################### 7 .data 8 msg1: .asciiz "tak(18,12,6)is: " 9 ####################################################### 10 .text 11 .globl main 12 main: 13 li $v0,4 #instruction 14 la $a0,msg1 15 syscall 16 17 ## 18 addiu $sp,$sp,-28 19 sw $ra,24($sp) 20 sw $fp,20($sp) 21 addiu $fp,$sp,24 22 ## 23 24 li $a0,18 #x==18 25 li $a1,12 #y==12 26 li $a2,6 #z==6 27 move $a3,$a2 28 jal tak 29 30 move $a0,$v0 #out put the result 31 li $v0,1 32 syscall 33 34 lw $ra,24($sp) #restore $ra 35 lw $fp,20($sp) #restore $fp 36 addiu $sp,$sp,28 #pop stack 37 38 li $v0,10 #YOU NEED ONE !!!!!!! 39 syscall 40 41 tak: 42 ## 43 addiu $sp,$sp,-28 #stack frame is 28 bytes long 44 sw $ra,24($sp) 45 sw $fp,20($sp) 46 addiu $fp,$sp,24 47 ## 48 49 sw $a0,4($fp) #x 50 lw $v0,4($fp) #x 51 sw $a1,8($fp) #y 52 lw $v1,8($fp) #y 53 sw $a2,12($fp) #z 54 bgt $a0,$a1,endless 55 move $v0,$a2 56 j end 57 58 endless: 59 # 60 lw $v1,4($fp) 61 addiu $a0,$v1,-1 #a==tak(x-1,y,z) 62 lw $a1,8($fp) 63 lw $a2,12($fp) 64 move $a3,$a2 65 jal tak 66 sw $v0,16($fp) 67 # 68 lw $v1,8($fp) #b==tak(y-1,z,x) 69 addiu $a0,$v1,-1 70 lw $a1,12($fp) 71 lw $a2,4($fp) 72 move $a3,$a2 73 jal tak 74 sw $v0,20($fp) 75 # 76 lw $v1,12($fp) #c==tak(z-1,x,y) 77 addiu $a0,$v1,-1 78 lw $a1,4($fp) 79 lw $a2,8($fp) 80 move $a3,$a2 81 jal tak 82 move $a2,$v0 83 # 84 lw $a0,16($fp) #answer==tak(a,b,c) 85 lw $a1,20($fp) 86 move $a3,$a2 87 jal tak 88 end: 89 lw,$ra,24($sp) 90 lw $fp,20($sp) 91 addiu $sp,$sp,28 92 jr $ra 93 94 ###########EOF######################### 95