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;
 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             利用宏
 67             li    $t0,100
 68             sw    $t0,i
 69         ######################
 70     }
 71 {
 72     语句:i=j;
 73     {
 74         #####################
 75         设i,j分别为$s0,$s1
 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 一些宏指令{
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         ror170             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:{
272     来品一品这代码
273         .data
274 msg:    .asciiz "input a char"
275         .text
276         .globl main
277         .ent main   #csl是你吗
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 main
298 
299 #发现just_so_so
300 }
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     .ent ret 
440     jr   $ra
441     .ent ret
442     }
443 }

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。