MIPS笔记整理

博主因笔记出现错误被指出,提醒写博客不能马虎。同时提到FIB的优化采用尾递归,并给出了转载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

检讨:

   笔记里出现了几个错误,被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,$0100
 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        

 

  

转载于:https://www.cnblogs.com/guaguastandup/p/10815732.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值