• MIPS汇编语言示例


    存储单位寻址

    lw $s1,8($a1)
    sw $s1,8($a1)
    lw rt,offset(rs) #源操作数为基址寻址
    sw rt,offset(rs) #目标操作数为基址寻址
    

    数组

    一下列举一些cpp到mips的转换:

    cin>>h;
    A[12] = A[8]+h;
    
    li 	$v0,5
    syscall
    move 	$s2,$v0
    #ori 	$s2,$v0,0
    lw 	$t0,32($s3) #4*8 = 32,基址寻址
    add 	$t0,$s2,$t0
    sw	$t0,48($s3) #4*12 = 48
    
    int array[1024];
    
    	.data
    array:	.space 4096 
    #	.word 1024 is ok
    
    int pof2[16] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
    
    pof2:	.word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16
    
    la		$a0,pof2
    lw		$s0,8($a0)
    
    lui		$s1,0x1234
    ori		$s1,$s1
    addi	        $t0,$0,100
    sw		$t0,0($s1)
    

    立即数寻址/寄存器寻址{addi/add (s0,)s1,5/$s2}

    赋值

    全局/static变量:

    	.data
    i	.word 100
    
    ####################
    		.data
    i:		.space 4
    ####################
    		.text
    la		$t0,i
    addi	        $t1,$0,100
    sw		$t1,0($t0)
    ####################
    li		$t0,100
    sw		$t0,i
    ####################
    
    #语句:i=j;
    ############################################
    #设i,j分别为$s1,$s0
    add  	$s1,$0,$s0
    ############################################
    #situation1:
    #i为动态变量,地址为0x12345678
    #j被指派到寄存器$s1
    ############################################
    lui 	$t0,0x1234      # $s1<----0x12340000
    ori 	$t0,$t0,0x5678  # $s1<----0x12345678
    lw  	$s1,0($t0)
    ############################################
    #situation2:
    #i,j均为动态变量,地址分别为
    #0x12345678,0x87654320
    ############################################
    lui  	$t0,0x1234  #取出来放到高位
    ori  	$t0,$t0,0x5678
    lw   	$t1,0($t0)
    lui  	$t0,0x8765
    ori  	$t0,0x4320
    sw   	$t1,0($t0)
    ############################################
    #i,j均为自动变量,宏寻址
    lw   	$t0,i 
    sw   	$t0,j 
    

    宏指令

    mult和div都是二元的,指令周期分别为32和38,它们的宏指令为三元

    mult	$a1,$s1
    mflo	$v0			#存低32位
    mfhi	$v1			#存高32位
    
    div	$a1,$s1
    mflo	$v0			#存商
    mfhi	$v1			#存余数
    
    #加载地址宏指令
    la		Rdest,address
    #加载立即数宏指令
    li		Rdest,imm
    
    #$at寄存器编号为1,给汇编程序使用,把address或者imm加载到$at里面
    lui		$at,imm		
    ori		Rdest,$at,imm
    
    move	        Rdest,Rsrc
    
    Rdest:	存放结果的寄存器
    Rsrc:	立即数或者寄存器名
    (rs/rt):源操作数
    rd:		目的操作数
    

    循环移位宏指令

    rol		Rd,Rs,Src2	#循环左移
    ror		Rd,Rs,Src2	#循环右移
    

    查看实现方法:

    #	rol
    srl		$at,Rs,32-sa	#假设sa = 1,则at = rs>>31,仅保留最高位
    sll		Rd,Rs,sa		#rd = rs<<1,向左移一位
    or		Rd,Rd,$at		#rd = (rs<<1)|(rs>>31)
    #	ror
    sll		$a1,Rs,32-sa
    sri		Rd,Rs,sa
    or		Rd,Rd,$at
    

    跳转

    blez 	$s6,Quiz	#小于等于0
    beqz 	$s6,Quiz	#等于0
    bgez 	$s6,Quiz	#大于等于0
    

    统计字符串中字符的数量

    la	 	$t2,str
    xor		$t1,$t1,$t1	#清空$t1
    
    nextCh:
    lb	$t0,($t2)	#load a byte from $t2(the string)
    begz	$t0,strEnd	
    addiu	$t1,$t1,1
    addiu	$t2,$t2,1	#t2地址加1,移动one byte
    j nextCh
    
    strEnd:
    

    sqrt函数的使用

    #$s0=sqrt($a0*$a0+$a1*a1);
    mult 	$a0,$a0
    mflo 	$t0        #注意这里体会只低位
    mult 	$a1,$a1
    mflo 	$t1
    add  	$a0,$t0,$t1
    jal  	srt        #call the sqrt function
    move 	$s0,$v0    #result of sqr is returned in $v0(standard convention)
    

    set操作

    slt			<
    seq			==
    sge			>=
    sle	sleu	        <=
    sne			!=
    

    跳转

    j		target	#无条件跳转
    beq		xxxxxx	#条件跳转
    #bne,bgez,bgtz,blez,bltz
    

    syscall

    # 指令编号(服务号)放入:$v0
    # 输入参数事先放入$a1,$a0
    # 执行syscall
    # 返回值在$v0中
    
    		.data
    msg:    .asciiz "input a char"、
    
    		.text
    		.globl 	main
    		.ent 	main   
    main:   
    		li 		$v0,4
    		la 		$a0,msg
    		syscall
    
    		li 		$v0,12
    		syscall
    		move 	        $a1,$v0
    
    		li 		$v0,11
    		li 		$a0,0x0a 
    		syscall
    
    		move 	        $a0,$a1
    		li 		$v0,11
    		syscall
    
    		li 		$v0,10
    		syscall
    		.end main
    

    while循环/for循环

    v0=1;
    while(a1<a1){
        t1=mem[a1];
        t2=mem[a2];
        if(t1!=t2)break;
        a1++;
        a2--;     
    }
    v0=0;
    return 0;
    
    	li		$v0,1
    loop:
    	bgeu	        $a1,$a2,done
    	lb		$t1,0($a1)
    	lb		$t2,0($a2)
    	bne		$t1,$t2,break
    	addi	        $a1,$a1,1
    	addi	        $a2,$a2,-1
    	b		loop
    break:
    	li		$v0,1
    
    a0 = 0;
    for(int t0 = 10;t0>0;t0--)
        a0+=t0;
    
    	li		$a0,1
    	li		$t0,10
    loop:
    	add		$a0,$a0,$t0
    	addi	        $t0,$t0,-1
    	bgtz	        $t0,loop
    

    switch语句:

    s0=32
    top:
        cout<<"input a value from 1 to 3";
        cin>>v0;
        switch(v0){
            case(1){s0<<=1;break;}
            case(2){s0<<=2;break;}
            case(3){s0<<=3;break;}
            defalt:goto top;
        }
        cout<<s0;
    
                .data
                .align  2          
    ###############################################################
    # 插播一个小知识:
    #   alignment:
    #   字节:占用一个内存单元
    #   半字:占用相邻两个内存单元,地址必须为偶地址,末尾至少1个0
    #   字:四个,末尾至少2个0
    #   双字:八个,被8整除,末尾至少3个0
    #	因为MIPS指令字规模是32bits定长,所以每次都要以字对齐的方式在内存中存放指令
    #	所以要.align 2	#	貌似是4字节对齐
    #	"当一条指令已从内存取出并存放到指令寄存器(IR)中后,PC地址增量4"
    ###############################################################
    jumptable:  .word   top,case1,case2,case3
    msg:        .asciiz "
    
    input a value from 1 to 3:"
                .text
    top:
                li    $v0,4
                la    $a0,msg
                syscall
    
                li    $v0,5
                syscall
    
                blez  $v0,top
                li    $t3,3
                bgt   $v0,$t3,top
    #################################################################################################
                la    $a1,jumptable   #jumptable的首地址保存在$a1寄存器里面
                sll   $t0,$v0,2       #这个程序利用输入的字符在jumptable里面寻址,地址是4个byte一个单元的
                                      #$t0是位移量,$a1是基地址 
                                      #compute word offset
                add   $t1,$a1,$t0     #$t1现在应该是一个在jumptable里的指针,那么也就是jumptable的基地址
                lw    $t2,0($t1)      #$t2:load an address from jumptable
                                      #访问主存单元寻址必须用lw Rt,offset(Rs)
                jr    $t2             #是你小伙计!!!!!
    ################################################################################################
    
    case1:      sll   $s0,$s0,1
                b     output
    case2:      sll   $s0,$s0,2
                b     output
    case3:      sll   $s0,$s0,3
    output:
                li    $v0,1
                move  $a0,$s0
                syscall
    
    

    寄存器 rigister 速度快,代价高,数量有限
    内存:速度慢,容量大,G字节规模,代价低
    高速缓冲储存器:cache
    符号扩展:将符号位扩展为高位数字
    二进制加法;不同符号只要不溢出可以直接相加
    二进制减法:减数取负然后二进制加法
    溢出检测:
    符号不同:不可能溢出
    符号相同:必须和操作数有相同的符号,否则溢出
    ATTENTION:最高位进位不一定溢出,两个负数相加一定进位但不一定溢出

    la	$a0,string	#string的起始位置在$a0处
    jal	string_len	
    move	$t0,$v0		#调用结束,$v0被存放了string_len的结果,将$v0的值放入$t0
    
    		.text
    		.globl	main
    		.ent 	main
    main:
    	jal		ret			# way1 of calling function 
            la		$t0,ret		# way2 of calling function 
            jalr	        $ra,$t0
            li		$v0,1
            syscall
            .end	main
    ret:	
            jr		$ra
    
    ##########################################
    #HOMEWORK4:Fibonacci
    #Rabbit array
    #Editor:VScode
    ##########################################
    ##########################################
            .data
    msg1:   .asciiz "Now you have 10 rabbits~
    "
    msg2:   .asciiz "the Fibonacci number of 10 is : "
    msg3:   .asciiz "
    "
    ###########################################
            .text
            .globl main
    main:
    
        li    $v0,4
        la    $a0,msg1
        syscall
    
        ##1
        subi  $sp,$sp,32
        sw    $ra,28($sp)
        sw    $fp,24($sp)
        addiu $fp,$sp,28
        ##2
    
        li    $t0,10
        sw    $t0,16($sp)
    
        lw    $a0,16($sp)     #argument fib(n)
        jal   fib
        move  $t0,$v0
    
        li    $v0,4
        la    $a0,msg2
        syscall
    
        li    $v0,1
        move  $a0,$t0
        syscall
    
        lw    $ra,28($sp)
        lw    $fp,24($sp)
        addiu $sp,$sp,32
    
        li    $v0,10
        syscall
    
    fib:
                                #if(n==1||n==0)return 1;
                                #else return tailfib(n,1,1);
        addiu $sp,$sp,-24
        sw    $ra,20($sp)
        sw    $fp,16($sp)
        addiu $fp,$sp,20        #set up a frame pointer
    
        li    $t0,1
        sw    $a0,4($fp)        #save argument(n) fp4 saves n
    
        move  $v1,$a0
        beqz  $v1,then          #if n==0
        beq   $v1,$t0,then      #if n==1
    
        lw    $a0,4($fp)        #load argument(n)
        li    $a1,1             #$a1 is pre1
        move  $s3,$a0
        move  $s1,$t0
        move  $s2,$t0
        jal   tailfib
        j done
    
    then:
    
        li   $v0,1
        j    done
    
    done:
    
        lw    $ra,20($sp)
        lw    $fp,16($sp)
        addiu $sp,$sp,24
        jr    $ra
        .end  fact
    
    tailfib:
        li     $t1,2
        beq    $s3,$t1,then1
        lw     $v0,4($sp)
        add    $v0,$s1,$s2
        move   $s2,$s1
        move   $s1,$v0
        sub    $s3,$s3,1
        sw     $v0,4($sp)
        j      tailfib
    
    then1:
        lw     $v0,4($sp)
        jr     $ra
    
    
    ###########EOF############################
    
    #homework6:
    #       int tak(int x,int y,int z){
    #               x<=y?:z:tak(tak(x-1,y,z),tak(y-1,z,x),tak(z-1,x,y));
    #       }
    #editor:VScode
    #######################################################
               .data
    msg1:      .asciiz  "tak(18,12,6)is: "
    #######################################################
            .text
            .globl main
    main:
            li    $v0,4            #instruction
            la    $a0,msg1
            syscall
    
            ##
            addiu $sp,$sp,-28
               sw $ra,24($sp)
               sw $fp,20($sp)
            addiu $fp,$sp,24
            ##
    
            li     $a0,18            #x==18
            li     $a1,12            #y==12
            li     $a2,6            #z==6
            move   $a3,$a2
            jal     tak
    
            move $a0,$v0        #out put the result
            li $v0,1
            syscall
    
            lw $ra,24($sp)        #restore $ra
            lw $fp,20($sp)        #restore $fp
            addiu $sp,$sp,28    #pop stack
    
            li    $v0,10        #YOU NEED ONE !!!!!!!
            syscall
    
    tak:
            ##
            addiu $sp,$sp,-28    #stack frame is 28 bytes long
            sw $ra,24($sp)
            sw $fp,20($sp)
            addiu $fp,$sp,24
            ##
    
            sw $a0,4($fp)        #x
            lw $v0,4($fp)        #x
            sw $a1,8($fp)        #y
            lw $v1,8($fp)        #y
            sw $a2,12($fp)       #z
            bgt $a0,$a1,endless
            move $v0,$a2
            j end
    
    endless:
            #
            lw  $v1,4($fp)
            addiu $a0,$v1,-1    #a==tak(x-1,y,z)
            lw $a1,8($fp)
            lw $a2,12($fp)
            move    $a3,$a2
            jal tak
            sw $v0,16($fp)
            #
            lw $v1,8($fp)        #b==tak(y-1,z,x)
            addiu $a0,$v1,-1
            lw $a1,12($fp)
            lw $a2,4($fp)
            move    $a3,$a2
            jal tak
            sw $v0,20($fp)
            #
            lw $v1,12($fp)        #c==tak(z-1,x,y)
            addiu $a0,$v1,-1
            lw $a1,4($fp)
            lw $a2,8($fp)
            move $a3,$a2
            jal tak
            move $a2,$v0
            #
            lw $a0,16($fp)        #answer==tak(a,b,c)
            lw $a1,20($fp)
            move    $a3,$a2
            jal tak
    end:
            lw,$ra,24($sp)
            lw $fp,20($sp)
            addiu $sp,$sp,28
            jr $ra
    
    ###########EOF#########################
    
  • 相关阅读:
    json for modern c++(nlohmann json)使用小计
    你到底是如何上网的[转载]
    opencv编译
    二维码解析(编译zxing-cpp)
    otl odbc小计
    解决github clone慢的问题
    网络编程小计
    模板小计
    c++开发遇到的错误和引用配置
    IOCP Input/Output Completion Port IO完成端口
  • 原文地址:https://www.cnblogs.com/guaguastandup/p/10815732.html
Copyright © 2020-2023  润新知