MIPS汇编程序设计
mips 汇编代码
MIPS汇编代码MIPS汇编代码是MIPS微处理器的汇编语言,由MIPS Technologies公司开发。
它是一种低级编程语言,允许程序员直接控制处理器的寄存器和指令。
MIPS汇编代码通常用于嵌入式系统和实时系统,因为它可以提供对硬件的精细控制和高性能。
MIPS汇编代码由一系列指令组成,每条指令由一个操作码和零个或多个操作数组成。
操作码指定要执行的操作,而操作数指定操作的参数。
MIPS汇编代码中的指令可以分为以下几类:算术和逻辑指令:这些指令用于执行算术和逻辑运算,例如加、减、乘、除、与、或、非等。
数据传送指令:这些指令用于在寄存器和内存之间传送数据。
控制流指令:这些指令用于控制程序的执行流程,例如跳转、分支、调用和返回等。
系统指令:这些指令用于与系统进行交互,例如加载和存储程序和数据、读写I/O设备等。
MIPS汇编代码通常使用以下语法:label: instruction operand1, operand2, ...其中,label是指令的标签,instruction是指令的操作码,operand1、operand2等是指令的操作数。
MIPS汇编代码的程序结构通常包括以下几个部分:数据段:数据段用于存储程序中使用的数据,包括常量、变量和数组等。
代码段:代码段用于存储程序的指令。
堆栈段:堆栈段用于存储程序的局部变量和临时数据。
MIPS汇编代码的编译过程通常包括以下几个步骤:预处理:预处理阶段将源代码中的宏和条件编译指令进行处理。
汇编:汇编阶段将源代码中的指令转换成机器码。
链接:链接阶段将汇编生成的机器码与库函数和系统库进行链接,生成可执行文件。
MIPS汇编代码的优点包括:高性能:MIPS汇编代码可以提供高性能,因为它可以直接控制处理器的寄存器和指令。
精细的控制:MIPS汇编代码允许程序员对硬件进行精细的控制,这对于嵌入式系统和实时系统非常重要。
可移植性:MIPS汇编代码可以移植到不同的MIPS处理器上,因为MIPS处理器具有相同的指令集架构。
【参考文档】mips汇编范例-范文模板 (13页)
本文部分内容来自网络整理,本司不为其真实性负责,如有异议或侵权请及时联系,本司将立即删除!== 本文为word格式,下载后可方便编辑和修改! ==mips汇编范例篇一:MIPS汇编范例mips汇编语言之实现swap函数收藏此程序用来交换两个整数已在pcspim下编译通过#########################################################programed by stevie zou #### purpose:to swap two values ######10-15-201X######### ############################### text segment ###############.text.globl mainmain: la$t0, number #读取两个整数并放入寄存器$t1,$t2lw$t1, 0($t0)lw$t2, 4($t0)li$v0, 4#打印msg1la$a0, msg1li$v0, 1 #打印转换前$t1中的值move $a0, $t1syscallli$v0, 4 #打印msg2la$a0, msg2syscallli$v0, 1#打印转换前$t2中的值move $a0, $t2syscallmove $t3, $t1#关键部分,在寄存器间move数据move $t1, $t2move $t2, $t3li$v0, 4 #打印msg3la$a0, msg3syscallli$v0, 1 #打印转换后$t1中的值move $a0, $t1syscallli$v0, 4#打印换行符 /nla$a0, msg4syscallli$v0, 1#打印转换后$t2中的值move $a0, $t2########### data segment ##############.datanumber: .word 12,34msg1: .asciiz "the first number is:\n"msg2: .asciiz "\nthe second number is:\n"msg3: .asciiz "\nnow they are swapped as:\n"msg4: .ascii"\n"## end of file程序运行结果为:本文来自CSDN博客,转载请标出处明:mips汇编简单实例——一个小计算器收藏其实开始的时候一直在看 mips的指令格式,看了、忘了,没什么效果。
MIPS 指令系统和汇编语言
其中 A1 为目的操作数地址,A2 为源操作数地址。 指令的含义:(A1)OP(A2)→A1。 (3)一地址指令 一地址指令顾名思义只有一个显地址,它的指令格式为: OP A1
一地址指令只有一个地址, 那么另一个操作数来自何方呢?指令中虽未明显给出,但按事 先约定,这个隐含的操作数就放在一个专门的寄存器中。因为这个寄存器在连续性运算时,保 存着多条指令连续操作的累计结果,故称为累加寄存器(AC) 。 指令的含义:(AC)OP(A1)→AC (4)零地址指令 零地址指令格式中只有操作码字段,没有地址码字段,其格式为: OP 零地址的运算类指令仅用在堆栈计算机中的。 堆栈计算机没有一般计算机中必备的通用寄 存器,因此堆栈就成为提供操作数和保存运算结果的唯一场所。通常,参加运算的两个操作数 隐含地从堆栈顶部(栈顶和次栈顶单元)弹出,送到运算器中进行运算,运算的结果再隐含地 压入堆栈中。对于同一个问题,用三地址指令编写的程序最短,但指令长度(程序存储量)最 长;而用二、一、零地址指令来编写程序,程序的长度一个比一个长,但指令的长度一个比一 个短。
作码结构等,是一个很复杂的问题,它与计算机系统结构、数据表示方法、指令功能设计等都 密切相关。
指令的基本格式
一条指令就是机器语言的一个语句, 它是一组有意义的二进制代码, 指令的基本格式如下: 操作码字段 地址码字段
其中操作码指明了指令的操作性质及功能,地址码则给出了操作数的地址。 指令的长度是指一条指令中所包含的二进制代码的位数, 指令长度与机器字长没有固定的 关系,它可以等于机器字长,也可以大于或小于机器字长。通常,把指令长度等于机器字长的 指令称为单字长指令; 指令长度等于半个机器字长的指令称为半字长指令;指令长度等于两个 机器字长的指令称为双字长指令。 在一个指令系统中,若所有指令的长度都是相等的,称为定长指令字结构。定长结构指令 系统控制简单,但不够灵活。若各种指令的长度随指令功能而异,就称为变长指令字结构。现 代计算机广泛采用变长指令字结构,变长结构指令系统灵活,但指令的控制较复杂。 计算机执行一条指令所需要的全部信息都必须包含在指令中。 对于一般的双操作数运算类 指令来说,除去操作码之外,地址码字段中应包含以下信息: 第一操作数地址。 第二操作数地址。 操作结果存放地址。 这些信息可以在指令中明显的给出,称为显地址;也可以依照某种事先的约定,用隐含的 方式给出,称为隐地址。所以,从地址结构的角度可以分为三地址指令、二地址指令、一地址 指令和零地址指令。 (1)三地址指令 三地址指令格式为: OP A1 A2 A3
基于MIPS指令集的汇编程序(spim仿真)——快速排序和二分搜索
Report for MIPS Assembler ProgramsQuick Sort and Binary SearchHAO Cong1. IntroductionIn this program, I implemented two major functions: quick sort and binary search. First, a list of integers is given by user, and the integers are sorted in ascending order using quick sort method. Then the program search for the particular integer given by user, using binary search, and provides its position. Figure 1 shows the basic structure of the program.Figure 1: Basic Structure of Program2. Implementation2.1 Quick Sort2.1.1 Brief Introduction to Quick Sort①Quicksort sorts by employing a divide and conquer strategy to divide a list into two sub-lists.The steps are:1. Pick an element, called a pivot, from the list.2. Reorder the list so that all elements with values less than the pivot comebefore the pivot, while all elements with values greater than the pivot comeafter it (equal values can go either way). After this partitioning, the pivot is inits final position. This is called the partition operation.3. Recursively sort the sub-list of lesser elements and the sub-list of greaterelements.The base case of the recursion is list of size zero or one, which never need to be sorted.2.1.2 Pseudo code2.1.3 Implementation of Quick SortEven having written C code, it’s not easy to change into assembler code. The most difficult part is applying the recursive method. We have to take care of building Stack Frame and storing registers. Now I’d like to take several parts of the code to make detailedexplanation.Firstly,we claim 1024bytes in memory, in order to store the integers to be sorted. Use .data to put them in data segment. From now on, all operations on integers are based on memory.Here, we begin to call the function of quick sort. In MIPS, when calling other functions, parameters are stored in $a0 - $a3. So we put the begin index and end index in $a0 and $a1, then the parameters are transferred to sub-functions.In order to jump, we used instruction jal. Using this, the return address can be stored in $ra atomatically. So when caller ends, PC pointer can return to the next instruction of callee after jal to continue.This is the end condition of recursive. If the left list has only one element, the program should return and end recursive. In this case we don’t need to build a stack frame for callee. It can save execution time.At the beginning of a callee, it must:a) Create a stack frame, by subtracting the frame size from the stack pointer ($sp). In MIPS, the minimum stack frame size is 32 bytes, so even if the program doesn't need all of this space, stack frames still should be made this large.b) Save any callee-saved registers ($s0 - $s7, $fp, $ra) which are used by the callee. In this program, only $fp and $ra need to be saved.c) Set the frame pointer to the stack pointer, plus the frame size.Here we calculate the pivot value: the average of first and last element.Given middle value, we begin to compare from both beginning and ending of the list. From the beginning, we try to find the first integer that is lager than pivot value; from the end, we try to find the first integer that is smaller than pivot value. If the two pointers haven’t touch, do swap. Otherwise, do partition.The above figure shows the branch flow. In order to make it clear, I hided detailed code.Besides, I used instruction b/bgt/ble/blt/bge here, instead of jump instructions. Their functions are similar, but there’re also some differences between them. One is jump instructions will automatically store the return address in $ra, but branch instructions don’t. Here, we only need to implement the function of if-else, so branch instruction is OK.Here is recursive call. Since the function call will change the values in registers, the values must be pushed in stack before calling sub-functions and be popped after calling. So the sw instruction is used to preserve and lw is used to restore.In MIPS, there’s a common custom, that is, $t0-$t7 is called Temporary Register, and $s0-s7 is called Saved Register. In general, the caller should take charge of keep the value of $t0-$t7, if necessary, and the callee has the responsibility to save $s0-$s7. In other words, $t0-$t7 is “temporary” to caller, because callee may modifies it, so caller has to preserve them; but $s0-$s7 is “saved” to caller, because callee will save them and restore them before return, so caller doesn’t need to care. Keeping this custom does help to create good program, I think.At last, before function returns, it restore the $ra, $fp and other registers such as$s0-$s7, and jump to return address.So in this way, quick sort is implemented successfully. The sorted integers are kept in memory in order and can be output by using syscall. Input and output is quite easy, so I won’t introduce here.2.1 Binary Search2.2.1 Brief Introduction to Binary SearchBinary search is one of the searching algorithms, which is widely used in finding a given number in a list of sorted numbers. It’s time complexity is O(logn) and memory complexity is O(n).At the beginning, we pick up the number in the middle and compare it with the given one. If the given one is larger than the middle one, we go on searching the back half of the list, and if the given one is smaller than the middle one, we go on searching the front half of the list. Repeat this procedure until the number is found or cannot divide any more. In this way, we throw half of the numbers each comparison. So it’s called binary search.2.2.2 Implementation of Binary SearchCompared with quick sort, binary search is easier and doesn’t need recursive. However, I will also make a brief explanation on binary search.Here we begin binary search. The function needs two parameters: left index and right index.In the above segment, $t0 is the given number, and $t4 is the middle number. We can clearly see that if the given one is larger than the middle one, we go on searching the back half, and if the given one is smaller than the middle one, we go on searching the front half. If equal, target number is found, and program jump to print the result.If the target number is supposed in front half, we should move the right pointer to middle, otherwise, if it’s supposed in back half, we move the left pointer to middle.Of course, if at last there remains only two numbers and cannot be divided any more, compare the target number with both of them. If still not hit, just tell that the target number cannot be found.In this way, binary search is implemented successfully.3. Execution ResultsThe following figures show the execution results of this program. The first figure shows the whole picture while running. Figure 2 shows detailed result, including both sorting and searching. And figure 3 shows that the program can successfully deal with some complex situations, such as repeating numbers.Figure 1: Whole picture when runningFigure 2: More detailed resultFigure 3: Successfully deals with repeating numbers4. Code## HAO Cong -- 2010/12/15 - 2010/12/19## QuickSort_BinarySearch.asm -- A program for quick sort and binary search.dataarray: .space 1024num_of_integer: .word 0comment_msg: .asciiz "This is a program for quick sort and binary search.\n"input_msg: .asciiz "Please input the integers(-1 to quit):"search_msg: .asciiz "Please input a target integer:"not_found: .asciiz "Sorry, the integer does not exist."pos: .asciiz "Position: "thanks: .asciiz "Thanks for using!\n"newline: .asciiz "\n"whitespace: .asciiz " ".text.globl mainmain:la $a0, comment_msg # print the promoting message to screenli $v0, 4syscallmove $t7, $zero # t7 stores the number of integersla $t6, array # get base address of array and store in t6input:la $a0, input_msg # print the input message for userli $v0, 4syscallli $v0, 5 # read an integer from usersyscallli $t0, -1beq $v0, $t0, end_input # end input if integer is -1move $t0, $t7mul $t0, $t0, 4 # calculate offset addressaddu $t1, $t0, $t6 # calculate the actual address of the integer in memorysw $v0, ($t1) # store the integer to memoryaddu $t7, $t7, 1 # total number plus oneb input # go on inputend_input:sw $t7, num_of_integer # store the number of integers into memoryquick_sort_begin:li $a0, 0 # $a0: start indexsubu $a1, $t7, 1 # $a1: end indexjal quick_sort # call quick_sortoutput:lw $t1, num_of_integer # get the number of integers and keeps in $t1 li $t2, 0out_loop:beqz $t1, search # if $t1 decrease to zero, end the programsubu $t1, $t1, 1 # minus t1 by onemul $t3, $t2, 4 # calculate the integer's addressla $t4, arrayaddu $t4, $t3, $t4lw $a0, ($t4) # print one integerli $v0, 1syscallla $a0, whitespaceli $v0, 4syscalladdu $t2, $t2, 1 # $t2 plus oneb out_loopsearch:la $a0, newline # change a new lineli $v0, 4syscallla $a0, search_msg # print the input message for userli $v0, 4syscallli $v0, 5 # read an integer from usersyscallli $t0, -1beq $v0, $t0, end_program # end input if integer is -1b binary_searchend_program:la $a0, thanksli $v0, 4syscallli $v0, 10syscallquick_sort:bgt $a1, $a0, quick_sort_partition # if end index is larger than start index, do partition jr $ra # just return without doing nothingquick_sort_partition:subu $sp, $sp, 32 # frame size = 32sw $fp, 28($sp) # preserve the Frame Pointersw $ra, 24($sp) # preserve the Return Addressaddu $fp, $sp, 32 # move Frame Pointer to new basemove $t0, $a0 # put start index in $t0move $t1, $a1 # put end index in $t1la $t2, array # put array's base address in $t2mul $t3, $t0, 4addu $t3, $t3, $t2lw $t3, ($t3) # find the integer whose index is $t0mul $t4, $t1, 4addu $t4, $t4, $t2lw $t4, ($t4) # find the integer whose index is $t1li $t6, 2addu $t7, $t3, $t4divu $t5, $t7, $t6 # calculate the middle value: ( first + last ) / 2 , store in $t5move $s0, $t0move $s1, $t1 # backup $t0 and $t1sort_loop:left_half:bge $s0, $t1, right_half # if left pointer is larger than or equal to end index, jump outmul $s2, $s0, 4addu $s2, $s2, $t2 # the integer's address is in $s2lw $s3, ($s2) # get the integer whose index is $s0, put it in $s3bge $s3, $t5, right_half # if current integer is bigger than middle value, do right half addu $s0, $s0, 1 # $s0 plus oneb left_halfright_half:ble $s1, $t0, do_swap # if right pointer is smaller than or equal to start index, jump out of loopmul $s4, $s1, 4addu $s4, $s4, $t2 # the integer's address is in $s4lw $s5, ($s4) # get the integer whose index is $s1, put it in $s5ble $s5, $t5, do_swap # if the current integer is smaller than middle value, do swap subu $s1, $s1, 1 # $s1 minus oneb right_halfdo_swap:bgt $s0, $s1, partition # if left pointer is bigger than right pointer, do partitionmul $s2, $s0, 4addu $s2, $s2, $t2 # the integer's address is in $s2lw $s3, ($s2) # get the integer whose index is $s0, put it in $s3mul $s4, $s1, 4addu $s4, $s4, $t2 # the integer's address is in $s4lw $s5, ($s4) # get the integer whose index is $s1, put it in $s5sw $s3, ($s4)sw $s5, ($s2) # swap the two integers in memorybeq $s0, $t1, sort_loopaddu $s0, $s0, 1 # $s0 plus onebeq $s1, $t0, sort_loopsubu $s1, $s1, 1 # $s1 minus oneb sort_loop # go on sorting the integers partition:sw $s0, 20($sp) # preserve $s0 and $t1sw $t1, 16($sp)move $a0, $t0 # sort the left half of the arraymove $a1, $s1 # start from $t0 and end at $s1jal quick_sortlw $s0, 20($sp)lw $t1, 16($sp)move $a0, $s0 # sort the right half of the arraymove $a1, $t1 # start from $s0 and end at $t1jal quick_sortreturn:lw $ra, 24($sp) # restore Return Addresslw $fp, 28($sp) # restore Frame Pointeraddu $sp, $sp, 32 # restore Stack Pointerjr $ra # returnbinary_search:move $t0, $v0 # get the number from usermove $t1, $zero # $t1 is left indexlw $t2, num_of_integersubu $t2, $t2, 1 # $t2 is right indexla $t7, array # put array's base address in $t7 search_loop:subu $t3, $t2, $t1li $t4, 1beq $t3, $t4, judgement # if right - left = 1, compare the integer with both of themaddu $t3, $t1, $t2li $t4, 2div $t3, $t3, $t4 # middle index is ( left + right ) / 2, put in $t3move $t4, $t3mul $t4, $t4, 4addu $t4, $t4, $t7 # the integer's address is in $t4lw $t4, ($t4) # get the integer whose index is $t4, and still put it in $t4 blt $t0, $t4, front_half # if $t0 < $t4, find it in the front halfbgt $t0, $t4, back_half # if $t0 > $t4, find it in the back halfmove $a0, $t3 # if $t0 = $t4, the integer is foundjal get_resultjudgement:move $t5, $t1mul $t5, $t5, 4addu $t5, $t5, $t7lw $t6, ($t5) # find the integer with index of $t1, and put it in $t6move $a0, $t1beq $t0, $t6, jump_to_resultmove $t5, $t2mul $t5, $t5, 4addu $t5, $t5, $t7lw $t6, ($t5) # find the integer with index of $t2, and put it in $t6move $a0, $t2beq $t0, $t6, jump_to_resultla $a0, not_foundli $v0, 4syscallb searchjump_to_result:jal get_resultfront_half:move $t2, $t3 # move the right pointer to the middleb search_loopback_half:move $t1, $t3 # move the left pointer to the middleb search_loopget_result:move $t0, $a0addu $t0, $t0, 1la $a0, posli $v0, 4syscallmove $a0, $t0li $v0, 1syscallb searchReferences①Pick from /wiki/Quicksort, 2009。
学习龙芯汇编语言程序设计
第四篇,在 C 语言中嵌入汇编。
在 C 语言中直接使用机器指令。
第五篇,介绍一些指令(一般的指令直接看手册,只介绍需要注意的)
联机分时系统
六十年代末七十年代初最热的技术之一是联机分时系统。在这之前,程序员要使用计算机一 般是使用穿孔卡片或穿孔纸带,然后是排队,轮到后,独自占用。往往编译出错,便要把计 算机让给别人用,修改后,再排队,重复上面的过程。随着计算机的内存不断增大和速度不 断提高,技术人员就研究出了让多个用户分享一台计算机的办法。不但程序员获益(编辑, 编译,运行,好象独占一台电脑),商业用户也可以用来远程访问联机的数据库,这让计算 机的应用大为扩展,象银行异地处理业务,飞机订票管理这样的应用也可以实现了。专业厂 家的系统都很昂贵,而且和专有的硬件结合在一起,一般用户无法很便宜地获得。这些分时 系统有的使用字符终端,有的使用电传打字机(出于成本考虑,比终端便宜)。
在 UNIX 开发出来后,由于可移植,各种新开发的,更便宜的硬件上也能提供联机分时服务 了。
后来分时技术不断改进,现在已经有了基于网络的远程登陆,比如论坛大侠 lyxmoo 在拿到 龙芯盒子之后,慷慨提供 SSH 服务,让没有盒子的朋友们也能体验一下使用龙芯的感受。
以前提供分时服务的计算机,属于大型机(速度约每秒一百万次)。
通用寄存器$31还是处理器硬件约定的 JAL 指令的链接寄存器。(JALR 可以使用任何一个 通用寄存器)。通用寄存器$0,它的值恒为零。
由于 MIPS 采用将比较运算的结果放入任意一个指定的通用寄存器,所以龙芯没有整数比较 运算结果的标志寄存器(浮点运算使用状态寄存器的一个状态位)。
指令说明:
move 目的寄存器,源寄存器,表示把源寄存器的值传送至“目的寄存器”
MIPS指令系统和汇编语言
MIPS指令系统和汇编语言MIPS(Microprocessor without Interlocked Pipeline Stages)指令系统,是一种以RISC(Reduced Instruction Set Computer,精简指令集计算机)为基础的处理器架构。
作为一种广泛应用于嵌入式系统和计算机组成的指令集架构,MIPS指令系统以其简洁高效的特性而受到广泛关注和应用。
一、MIPS指令系统概述MIPS指令系统的设计目标之一是提高处理器的性能,并降低设计的复杂性。
它采用了统一的指令格式,包括操作码、源操作数以及目的操作数等字段,使得指令的译码和执行过程更加高效。
此外,MIPS的指令集还支持延迟槽、流水线和分支延迟等特性,以进一步提升指令执行的效率。
二、MIPS指令格式MIPS指令格式遵循统一的规则,包括三种基本类型的指令格式:R 型、I型和J型指令。
R型指令主要用于寄存器之间的操作,包括算术运算、逻辑运算等;I型指令用于立即数和寄存器之间的操作,涵盖了数据传输、分支跳转等功能;J型指令主要用于无条件跳转。
三、MIPS指令编码和寻址方式MIPS指令采用固定长度的指令编码格式,使得指令的解析和处理更加高效。
在寻址方面,MIPS支持多种寻址方式,包括立即寻址、寄存器寻址和间接寻址等。
这些灵活的寻址方式使得MIPS指令更加适用于不同的计算需求。
四、MIPS汇编语言MIPS汇编语言是一种用于编写MIPS指令的低级语言。
它是一种基于文本的表示形式,使用助记符来表示不同的指令和操作。
MIPS汇编语言具有简单易学的特性,更加接近底层硬件的工作原理,使得程序员可以更加精准地控制和优化程序的执行过程。
五、MIPS指令系统的应用由于MIPS指令系统的优越性能和灵活性,它被广泛应用于各种领域。
在嵌入式系统中,MIPS处理器可以实现高性能和低功耗的设计,广泛应用于智能手机、路由器、电视机等设备中。
在计算机组成和操作系统领域,MIPS指令系统被用于讲解和研究计算机的工作原理和底层机制。
MIPS微处理器原理-MIPS汇编语言
操作数:寄存器、存储器、常数
因常数的值可以立即访问,故又称为立即数(immediate)。
加立即数指令 ( addi ):
# $s0=a, $s1=b
addi $s0, $s1, 4 # a=b+4 addi $s1, $s0,-2 # b=a-2
没有NOT,可用下面代替 A NOR $0 = NOT A
Source Values $s1 0000 0000 0000 0000 0000 0000 1111 1111
andi rt、rs、imm
Assembly Code
imm 0000 0000 0000 0000 1111 1010 0011 0100
用途 常数0 汇编器临时变量 函数返回值 函数参数 临时变量 保存变量
名称 $t8 ~ $t9 $k0 ~$k1 $gp $sp $fp $ra
编号 24~25 26~27 28 29 30 31
用途
临时变量
操作系统临时变量
全局指针
栈指针
帧指针
保存变量
8
MIPS Register Set
Name $0 $at $v0-$v1 $a0-$a3 $t0-$t7 $s0-$s7 $t8-$t9 $k0-$k1 $gp $sp $fp $ra
4个准则: ① 简单设计有助于规整化; ② 加快常见功能; ③ 越小的设计越快; ④ 好的设计需要好的折中方法。
4
R I S C 指令集的特点
Reduced Instruction Set Computer Complex Instruction Set Computer
• 精简了指令系统,流水线以及常用指令均可用硬件执行;
MIPS汇编语言
MIPS 汇编语言–机器语言: –汇编语言:• C 代码•MIPS 汇编代码add a, b, c• C 代码•MIPS 汇编代码sub a, b, c简单设计有利于规整化• C 代码•MIPS 汇编代码add t, b, csub a,t,d加快常见的功能reduced instruction set computer (RISC), complex instruction set computers (CISC)• C 代码•MIPS 汇编代码sub a, b, c越小越快名字寄存器数量用途$0 0 常量0$at 1 汇编临时变量$v0-$v1 2-3 Function 返回值$a0-$a3 4-7 Function 参数$t0-$t7 8-15 临时变量$s0-$s7 16-23 保存变量$t8-$t9 24-25 更多临时变量$k0-$k1 26-27 OS 临时变量$gp 28 全局指针$sp 29 堆栈指针$fp 30 帧指针$ra 31 Function 返回地址• C 代码•MIPS 汇编代码add $s0, $s1, $s2# $s0 = a, $s1 = b, $s2 = c40F30788 01E E2842 F2F1A C07 A B C D E F78•lw $s0, 5($t1) #load word数据40F 3078801E E 2842F 2F 1A C 07A B C D E F 78•汇编代码lw $s3, 1($0)偏移可以写成十进制(缺省)或十六进制•汇编代码sw $t4, 0x7($0) 40F3078801E E2842F2F1A C07A B C D E F78数据宽 = 4 字节40F 3078801E E 2842F 2F 1A C 07A B C D E F 78•汇编代码lb $t4, 0x3($0) sb $t4, 0x3($0)好的设计需要好的折中。
MIPS指令集及汇编
和R12000(1997年)等型号。 z 随后,MIPS公司把重点放在嵌入式系统。
{ 1999年发布MIPS32和MIPS64架构标准,集成了所有原 来MIPS指令集,并且增加了许多更强大的功能。陆续开发 了高性能、低功耗的32位处理器内核(core)MIPS324Kc 与高性能64位处理器内核MIPS64 5Kc。
{ 应用广泛的32位MIPS CPU包括R2000,R3000 其ISA都是MIPS I,另一个广泛使用的、含有许多 重要改进的64位MIPS CPU R4000及其后续产 品,其ISA版本为MIPS III
一、 MIPS简介
{ 1984年,MIPS计算机公司成立。1992年,SGI收购了 MIPS计算机公司。1998年,MIPS脱离SGI,成为MIPS 技术公司。
龙芯2E笔记本电脑运行 OpenOffice打开Word文档
ቤተ መጻሕፍቲ ባይዱ
二、MIPS体系结构
{ 指令集体系结构类型:寄存器——寄存器型
(1)寄存器的特点 (2)整数乘法单元和寄存器 (3)寻址方式 (4)存储器和寄存器中的数据类型 (5)流水线冒险
二、 MIPS体系结构——(1)寄存器
{ MIPS 包含32个通用寄存器
{ 2000年,MIPS公司发布了针对MIPS32 4Kc的版本以及 64位MIPS 64 20Kc处理器内核。
一、 MIPS简介
{ 基于龙芯2E处理器的千元的PC、1999元的笔记本电脑、 意法半导体3000万元购买龙芯2E 5年的生产和销售权, 国产操作系统内核在龙芯2E上测试成功。
mips汇编语言代码示例
mips汇编语言代码示例MIPS汇编语言代码示例:计算两个数的和MIPS汇编语言是一种基于RISC(精简指令集计算机)架构的汇编语言,它被广泛应用于嵌入式系统、数字信号处理、计算机视觉等领域。
本文将以计算两个数的和为例,介绍MIPS汇编语言的基本语法和指令。
我们需要了解MIPS汇编语言的寄存器。
MIPS架构中有32个通用寄存器,分别用$0~$31表示。
其中,$0$寄存器始终为$0$,$1~$3寄存器用于函数调用,$4~$7寄存器用于保存函数调用时的参数,$8~$15寄存器用于保存临时变量,$16~$23寄存器用于保存全局变量,$24~$25寄存器用于保存函数调用时的返回值,$26~$27寄存器用于保存系统调用的参数,$28寄存器用于保存全局指针,$29寄存器用于保存栈指针,$30寄存器用于保存帧指针,$31寄存器用于保存程序计数器。
接下来,我们可以编写计算两个数的和的MIPS汇编语言代码。
假设我们要计算$a+b$的值,可以使用以下代码:```.dataa: .word 2b: .word 3sum: .word 0.text.globl mainmain:lw $t0, alw $t1, badd $t2, $t0, $t1sw $t2, sumli $v0, 10syscall```我们使用.data段定义了三个变量:$a$、$b$和$sum$。
$a$和$b$分别被初始化为$2$和$3$,$sum$被初始化为$0$。
接着,我们使用.text段定义了一个全局函数$main$,并使用.globl指令将其声明为全局函数。
在$main$函数中,我们首先使用lw指令将$a$和$b$的值分别加载到$t0$和$t1$寄存器中。
然后,我们使用add指令将$t0$和$t1$的值相加,并将结果保存到$t2$寄存器中。
最后,我们使用sw指令将$t2$的值存储到$sum$变量中。
最后,我们使用li指令将$v0$寄存器设置为$10$,并使用syscall指令退出程序。
MIPS GCC 嵌入式汇编(龙芯适用)
: output_operand
: input_operand
: clobbered_operand ); 以一个例子来说明: 如果我们要读取 CP0 25 号硬件计数寄存器的值,并返回之,可以这样:
int get_counter()
{ int rst;
asm(
"mfc0 %0, $25\t\n"
当前版本: 0.3 1. GCC 内嵌汇编的基本格式
asm("assembly code"); 如: asm("syscall"); //触发一个系统调用 如果有多条指令,则需在指令尾部添加'\t'和'\n',如:
asm("li v0, 4011\t\n" "syscall"); 括号里的字符串 GCC 前端不作分析,直接传给汇编器 as ,故而相联指令间需 插入换行符。 '\t' 加入只为排版对齐一些而已,可以使用 gcc -S tst.c -o tst.s 查看生成的 tst.s 因为 GCC 并不对 asm 后括号中的指令作分析,故而如果指令修改一些的寄存 器的值,GCC 是 不知道的,这个会引入一些问题。 另外 asm 可以替换为 __asm__ ,效果等价。__asm__ 一般用于头文件中,防 止关键字 asm 可能与一些变量、函数名冲突。 内嵌汇编如何与 C 变量交换数据? 2. GCC 内嵌汇编扩展格式 asm (
constant which is not `I', `K', or `L') `N' Negative 16-bit constant `O' Exact power of two `P' Positive 16-bit constant `G' Floating point zero `Q' Memory reference that can be loaded with more than one instruction (`m' is preferable for `asm' statements) `R' Memory reference that can be loaded with one instruction (`m' is preferable for `asm' statements) `S' Memory reference in external OSF/rose PIC format (`m' is preferable for `asm' statements) 5. 32 位下传递 64 位数据 A. 读取: long long counter; asm( ".set mips3\n\t" "dmfc0 %M0, $25\n\t" "dsll %L0, %M0, 32\n\t" "dsrl %M0, %M0, 32\n\t" "dsrl %L0, %L0, 32\n\t" ".set mips0\n\t" : "=r" (counter) ); B. 写入 long long counter = 0x0000001000000100; asm( ".set mips3\n\t" "dsll %L0, %L0, 32\n\t" "dsrl %L0, %L0, 32\n\t" "dsll %M0, %M0, 32\n\t" "or %L0, %L0, %M0\n\t" "dmtc0 %L0, $25\n\t" ".set mips0\n\t" : "=r" (counter) );
c语言 mips指令
c语言mips指令MIPS指令集是一种为MIPS架构的微处理器设计的计算机指令集。
这是一种RISC(精简指令集计算机)指令集,它的设计目标是使其在各种不同的硬件实现上都能高效地运行。
对于C语言,通常使用编译器将C代码编译成MIPS汇编指令。
例如,下面是一个简单的C程序,用于计算两个整数之和:c复制代码#include<stdio.h>int main() {int a = 5;int b = 10;int sum = a + b;printf("Sum is: %d\n", sum);return0;}这个程序可以编译成MIPS汇编语言,如下所示:assembly复制代码# MIPS assembly code for the above C program.text.globl mainmain:# Load the values of a and b into $t0 and $t1 respectivelyaddi $t0, $zero, 5 # Load the value of a into $t0addi $t1, $zero, 10 # Load the value of b into $t1add $t2, $t0, $t1 # Add the values in $t0 and $t1 and store the result in $t2 (sum)li $v0, 1 # Load the system call number for print_int into $v0 move $a0, $t2 # Move the value in $t2 (sum) into $a0, which is the first argument of print_intsyscall # Call the kernel to execute print_intli $v0, 10 # Load the system call number for exit into $v0syscall # Call the kernel to exit以上MIPS汇编代码对应于C程序的各个部分。
mips汇编指令手册
mips汇编指令手册摘要:一、概述MIPS汇编指令手册二、MIPS汇编指令的基本结构1.指令格式2.操作码和操作数3.寄存器文件三、数据传输指令1.加载和存储指令2.寄存器间的数据传输四、算术和逻辑指令1.加法和减法指令2.乘法和除法指令3.逻辑指令五、移位和位操作指令1.移位指令2.位操作指令六、条件跳转和分支指令1.无条件跳转指令2.条件跳转指令3.分支指令七、循环指令1.循环开始和结束指令2.循环计数指令八、调用和返回指令1.调用指令2.返回指令九、中断和异常处理指令1.中断指令2.异常处理指令十、系统调用指令1.系统调用指令概述2.常用系统调用举例正文:一、概述MIPS汇编指令手册MIPS(Microprocessor without Interlocking Protection Structures)是一种精简指令集计算机(RISC)架构,广泛应用于嵌入式系统和处理器设计。
MIPS汇编指令手册提供了详细的指令集和编程指南,帮助开发者更好地使用MIPS处理器。
本文将简要介绍MIPS汇编指令的基本结构和分类,以供参考。
二、MIPS汇编指令的基本结构1.指令格式MIPS汇编指令采用固定长度的指令格式,包括操作码和操作数。
操作码表示指令的类型,操作数表示指令处理的数据。
2.操作码和操作数MIPS汇编指令的操作码和操作数分为两类:立即数和寄存器。
立即数直接参与运算,而寄存器表示要从寄存器文件中操作的数据。
3.寄存器文件MIPS处理器具有31个通用寄存器,分为两组:一组是30个32位寄存器(X0-X29),另一组是1个32位通用寄存器(PC)。
三、数据传输指令数据传输指令主要用于在内存和寄存器之间传输数据。
1.加载和存储指令加载指令(LDR)将内存中的数据加载到寄存器中,存储指令(STR)将寄存器中的数据存储到内存中。
2.寄存器间的数据传输寄存器间的数据传输可以通过指令如:MOV、CMP等实现。
MIPS体系结构和汇编语言快速入门
MIPS体系结构和汇编语言快速入门一、MIPS体系结构概述(200字)MIPS处理器由五个流水线阶段组成:取指令(IF)、指令解码(ID)、执行(EX)、访存(MEM)和写回(WB)。
这种流水线架构能够并行处理多条指令,提高了处理器的性能。
二、MIPS汇编语言基础(400字)MIPS汇编语言是一种低级语言,与二进制机器码一一对应。
它使用助记符(mnemonics)来表示不同的指令和操作数。
MIPS指令主要分为以下几类:1.加载和存储指令:- lw $t, offset($s):从地址$s+offset处加载一个字,并存入寄存器$t中。
- sw $t, offset($s):将寄存器$t中的值存储到地址$s+offset处。
2.算术和逻辑指令:- add $d, $s, $t:将寄存器$s和$t中的值相加,结果存入寄存器$d中。
- sub $d, $s, $t:将寄存器$s和$t中的值相减,结果存入寄存器$d中。
- and $d, $s, $t:将寄存器$s和$t的值逐位与运算,结果存入寄存器$d中。
- or $d, $s, $t:将寄存器$s和$t的值逐位或运算,结果存入寄存器$d中。
3.分支和跳转指令:- beq $s, $t, offset:如果寄存器$s和$t的值相等,则跳转到当前PC加上offset的地址处。
- j target:无条件跳转到指定的目标地址。
三、MIPS程序示例(600字)下面是一个使用MIPS汇编语言编写的简单程序,用于计算斐波那契数列的第10个数:.dataresult: .space 4 # 用于存储结果.text.globl mainmain:#初始化前两个斐波那契数li $t0, 0 # 第一个数为0sw $t0, result # 存储到result中li $t1, 1 # 第二个数为1sw $t1, result+4 # 存储到result的下一个字节中#循环计算剩下的斐波那契数li $t2, 2 # 计数器初始值为2loop:add $t3, $t0, $t1 # 计算下一个数sw $t3, result+($t2*4) # 存储到result的下一个位置addi $t2, $t2, 1 # 计数器加1move $t0, $t1 # 更新前两个数move $t1, $t3blt $t2, 10, loop # 如果计数器小于10,跳转到loop处继续循环#输出结果li $v0, 1 # syscall代码1表示输出整数lw $a0, result+36 # 读取result的第10个字节syscall # 执行系统调用#程序结束li $v0, 10 # syscall代码10表示程序结束syscall代码中使用了伪指令(如.data和.text)来指定数据段和代码段。
MIPS教程
MIPS教程MIPS指令系统及MIPS汇编(基于MARS)汇编语⾔是使⽤符号格式表⽰指令,可直接⾯向机器内存以及寄存器的程序设计语⾔。
本部分主要学习内容包括:1、以MIPS指令系统为例,学习并掌握MIPS指令集及汇编语⾔,能够使⽤MIPS汇编语⾔编写顺序、分⽀、循环等具有特定功能的结构化程序,掌握函数调⽤及栈操作等汇编程序设计⽅法。
该部分内容请参考《数字设计和计算机体系结构》第6章2、熟练使⽤MARS⼯具软件,具备MARS调试汇编代码的能⼒,能使⽤MARS模拟CPU执⾏汇编指令,通过观察相应寄存器、存储等部件的变化情况,查看程序是否符合期望;能够使⽤MIPS汇编语⾔编写并⽣成MIPS CPU可执⾏的⼆进制机器指令,便于对后续实验中所设计的CPU进⾏功能测试。
具体请参考《MARS使⽤教程》MIPS体系结构的寄存器MIPS体系结构定义了32个寄存器通⽤寄存器标志由$符号开头,寄存器表⽰有两种⽅式直接使⽤该寄存器对应的编号,例如:从$0到$31使⽤对应的寄存器名称,例如:$t0,$t1,……, $sp等每个寄存器都有其特定的作⽤,有相应的规范,可参考《数字设计和计算机体系结构》第6章表6-1MIPS汇编语句MIPS汇编中⼀般有3类语句,通常是⼀个语句⼀⾏(1)可执⾏指令(instruction),是处理器⽣成在运⾏时执⾏的机器码,告诉处理器该做什么,⼀条可执⾏指令对应⼀条机器指令(2)伪指令(Extended (pseudo) instruction)和宏,简化编程⼈员的⼯作,由编译器编译成⼀条或多条可执⾏指令,常见的伪指令如move,la,li等(相应的伪指令在Mars中的Help中有解释)(3)汇编器指令(伪操作)(Directives),不会被编译器编译成可执⾏指令(或机器指令),会被翻译成预处理指令,⽤于指⽰编译器⼯作,⽤来定义段、分配内存变量等;汇编器指令不是指令集的⼀部分MIPS汇编语⾔指令格式: [ 标签:] 操作符 [ 操作数 ] [ #注释 ]标签:(可选),标记内存地址,必须跟冒号。
MIPS汇编
bne s,t,label if(s!=t)goto label,可能分支变体bnel
bnez s,label if(s!=0)goto label,可能分支变体bnezl
blez s,label if(s<=0)goto label),可能分支变体blezl
bltz s,label if(s<0)goto label),可能分支变体bltzl
hilo=(signed)s*(signed)t
and d,s,t d=s&t
and d,s,j (andi d,s,j),d=s&(unsigned)j,仅用于0<=j<65535, 对于更大的数要生成额外的指令
ldc2 d,addr 64位加载协处理器2寄存器,如果采用了协处理器2 并且宽度为64位的话
ll(load linked)和sc(store conditional)组成原子操作:
ll d,off(b) …… sc t,off(b)
ll从内存读取一个字,以实现接下来的RMW操作,sc向内
存中写入一个字,以完成前面的RMW操作。“ll d,off(b)”指令执
addiu d,s,j d=s+(signed)j
sub d,s,t
d=s-t,溢出时自陷
subu d,s,j d=s-j;addiu d,s,-j
div d,s,t 异常
有符号32位除法指令,在被零除和溢出条件下发生
divu $zero,s,t no checks,lo=s/t,hi=s%t
mult s,t
2
MIPS汇编程序框架
编辑ppt
3
.data伪指令
定义程序的数据段,程序的变量需要在该伪指令 下定义,汇编程序会分配和初始化变量的存储空间
mips汇编语言指令
mips汇编语言指令MIPS(Microprocessor without Interlocked Pipelined Stages)是一种常见的RISC(Reduced Instruction Set Computer)体系结构,广泛用于许多计算机体系结构和嵌入式系统中。
本文将对MIPS汇编语言指令进行详细介绍和解析。
一、MIPS汇编语言概述MIPS汇编语言是一种低级语言,用于直接操作计算机硬件。
其指令集由一系列操作码(Opcode)和操作数组成。
MIPS指令集基于三个基本原则:简单性、固定的指令长度和规则对齐。
MIPS指令主要包括算术操作指令、逻辑操作指令、控制类指令和数据传输指令等。
二、MIPS汇编语言的基本指令1. 算术操作指令MIPS提供了一系列算术操作指令,如add(加法)、sub(减法)、mul(乘法)和div(除法)等。
这些指令用于对寄存器中的数据进行算术运算,并将结果保存在目标寄存器中。
示例:add $t0, $s1, $s2 # 将$s1和$s2中的值相加,结果保存在$t0中2. 逻辑操作指令逻辑操作指令用于对寄存器中的数据进行逻辑运算,如and(逻辑与)、or(逻辑或)和not(逻辑非)等。
示例:and $t0, $s1, $s2 # 将$s1和$s2中的值进行逻辑与运算,并将结果保存在$t0中3. 控制类指令MIPS提供了一系列控制类指令,如beq(条件分支)、j(无条件跳转)和jr(函数返回)等。
这些指令用于改变程序执行的流程。
示例:beq $t0, $t1, label # 如果$t0和$t1中的值相等,则跳转到label处继续执行4. 数据传输指令数据传输指令用于在寄存器和存储器之间传输数据,如lw(从存储器中加载数据)和sw(将数据存储到存储器中)等。
示例:lw $t0, 0($s1) # 从地址$s1+0处加载数据,并保存到$t0中三、MIPS汇编语言的特点与优势1. 简洁性MIPS汇编语言指令集相对较为简单,指令数目较少,易于理解和学习。
mips汇编指令手册
mips汇编指令手册摘要:1.MIPS 汇编指令手册简介2.MIPS 汇编指令的分类3.MIPS 汇编指令的寻址方式4.MIPS 汇编指令的指令集5.MIPS 汇编指令的应用领域正文:1.MIPS 汇编指令手册简介MIPS 汇编指令手册是一本详细描述MIPS(Microprocessor without Interlocked Pipeline Stages,无锁流水线处理器)指令集的参考书。
MIPS 汇编指令手册包含了MIPS 处理器能够理解和执行的所有指令,以及这些指令的格式、功能和寻址方式等内容。
对于计算机体系结构和汇编语言程序设计等相关领域的研究者和开发者来说,MIPS 汇编指令手册是一本非常重要的参考资料。
2.MIPS 汇编指令的分类MIPS 汇编指令可以分为三类:(1)存储器指令:这类指令主要用于对存储器进行读写操作,包括加载(load)和存储(store)指令。
(2)算术逻辑指令:这类指令主要用于执行各种算术和逻辑运算,包括加法、减法、乘法、除法等运算指令,以及与、或、非等逻辑运算指令。
(3)转移指令:这类指令主要用于控制程序的执行流程,包括条件跳转、无条件跳转、循环等指令。
3.MIPS 汇编指令的寻址方式MIPS 汇编指令的寻址方式主要有以下几种:(1)直接寻址:指令中直接给出操作数的地址。
(2)间接寻址:指令中给出操作数的地址的地址,需要通过两次访问存储器才能获取到操作数。
(3)寄存器寻址:指令中给出操作数在寄存器中的名字。
(4)立即寻址:指令中直接给出操作数,操作数紧跟在指令后面。
4.MIPS 汇编指令的指令集MIPS 汇编指令集包含了大量的指令,这里列举一些常见的指令:(1)加载指令:load(2)存储指令:store(3)算术运算指令:add、sub、mul、div(4)逻辑运算指令:and、or、not(5)转移指令:jmp、jz、jnz、循环指令等5.MIPS 汇编指令的应用领域MIPS 汇编指令广泛应用于计算机体系结构、操作系统、编译原理等领域。
微机原理实验报告
微机原理实验报告实验名称:MIPS汇编程序设计院系:电信学院班级:姓名:指导老师:一、实验目的:1.熟悉MIPS汇编程序开发环境,学习使用Qtstim工具。
知道如何查看内存空间分配。
2. 了解C语言语句与汇编指令之间的关系。
3. 掌握MIPS汇编程序设计,掌握QTSPIM的调试技术。
4. 了解MIPS汇编语言与机器语言之间的对应关系。
5. 熟悉常见的MIPS汇编指令6. 掌握程序的内存映像。
二、实验内容1.用汇编程序实现以下伪代码:要求使用移位指令实现乘除法运算。
Int main (){Int K,Y;Int Z[50];Y=56;For(k=0;k<50;K++) Z[k]=Y-16*(k/4+210);}三、程序设计及分析1.C语言分析:有两个变量是int型,一个数组型;还有一个循环执行过程。
2.汇编程序实现分析:首先需要定义用户数据段,获得一个内存空间作为数组空间。
再选定几个存放器作为K,Y以及输出,其中输出输出和Y可以合用一个存放器。
3.设计思路:分配完空间地址后,最重要的是完成循环控制。
循环控制有两个思路:可以是先判断后循环;或者是先循环后判断 即如图slti $t2,$t0,50 #判断k 是否于50beq $t2,$t3〔$t2=1循环,否那么结束。
〕四、程序实现及调试分析1.汇编程序代码实现:方法一.data #定义用户数据段z:.space 200 #数组为int型,大小为50,所以占内存4*50 str:.asciiz " "#输出结果之间的空隙.textmain:la $s0,z #$s0 #为数组在z[]li $t0,0 #$s1 #代表k计数,初始值为0li $t1,56 #$t2 #代表Y,初值为56loop:slti $t2,$t0,50 #判断k是否于50beq $t2,$0,done #当k大于等于50,跳转结束srl $t3,$t0,2 #k/4addi $t3,$t3,210 #k/4+210sll $t3,$t3,4 #16*(k/4+210)sub $t3,$t1,$t3 #y-16*(k/4+210)sw $t3,0($s0) #写进z[k]li $v0,1 #输出addi $a0,$s0,0syscallli $v0,4 #输出间隔la $a0,strsyscalladdi $s0,$s0,4 #地址移一位addi $t0,$t0,1 #k加1j loop #循环done:li $v0,10syscall2.调试过程1.编写程序:详细见代码2.装载程序选择file,选择Reinitialize and Load File,把写好的文件导入QtSpim。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微机原理实验报告MIPS汇编程序设计
院系:电子信息与通信学院
班级:电信卓越1201班
姓名:钟远维
学号:U201213500
一.实验目的
1. 掌握QTSPIM的调试技术
2. 了解MIPS汇编语言与机器语言之间的对应关系
3. 掌握MIPS汇编程序设计
4. 了解C语言语句与汇编指令之间的关系
5. 熟悉常见的MIPS汇编指令
6. 掌握程序的内存映像
二.实验任务
用汇编程序实现以下伪代码:要求采用移位指令实现乘除法运算。
int main()
{ int K, Y ;
int Z[50] ;
Y = 56;
for(k=0;k<50;k++)
Z[K] = Y - 16 * ( K / 4 + 210) ;
}
三.汇编源程序设计
1.算法设计
.data
#定义用户数据段
Z:.space 200
.text
#定义用户程序段
main:
#给K,Y分配寄存器并赋初值
#给数组Z[K]分配寄存器
#计算Y - 16 * ( K / 4 + 210) 并将结果存入一个寄存器
#将上述寄存器中的结果写入Z[K]
done:
li $v0,10
syscall
2.源程序代码
.data #定义用户数据段
z: .space 200
.text
main:
la $s0,z #$s0=addrz
li $t0,0 #$s1=k=0
li $t1,56 #$s2=y=56
loop:
slti $t2,$t0,50 #判断k是否于50
beq $t2,$0,done #当k大于等于50,跳转
srl $t3,$t0,2 #k/4
addi $t3,$t3,210 #k/4+210
sll $t3,$t3,4 #16*(k/4+210)
sub $t3,$t1,$t3 #y-16*(k/4+210)
sw $t3,0($s0) #写进z[k]
addi $s0,$s0,4 #地址移一位
addi $t0,$t0,1 #k加1
j loop #循环
done:
li $v0 10
syscall
四.源代码调试过程
1.装载程序。
点击file,选择Reinitialize and Load File,把写好的文件导入QtSpim。
2.点击“运行”,如图:
3.得到实验结果如下:
数据段映像:
仿真器在真正的用户代码段内增加了部分代码以实现程序运行控制,该仿真器中所有用户代码都必须存储在地址为0x00400000~0x00440000的范围之内。
用户代码段将每一行代码的地址,及其对应的机器码都显示给用户,为方便查看,还给出了反汇编得到的汇编指令,而且在注释中显示了用户编写的源代码。
通过地址部分信息,我们知道每一行代码的地址都是前一行代码地址+4,即PC+4,机器指令,例如
[00400044] 012b5822 sub $11, $9, $11 ; 14: sub $t3,$t1,$t3
其中的机器码012b5822=000000 01001 01011 01011 00000 100010B。
第一段六位和第六段六位分别为000000B和100010B表示该指令的功能为sub 指令,第二段5位为01001B表示第一个源操作数寄存器的编号($t1的编号为9),第三段5位为01011B表示第二个源操作数寄存器的编号($t3的编号为11),第四段5位为01011B表示目的操作数的寄存器编号($t3的编号为11),反汇编得到的汇编指令也很明显地指出了这些数据代表的意义;第五段在这条指令中没有意义。
其他行数据所表达的意义以此类推同样可以得到。
Z[k]数据内存映像:
整理成表格形式如下:
可以看到Z[K]的首地址为10010000,且每个内存中的四个数值都是一样的,且随着地址规律地增加,数值在规律地递减。
五.实验总结
通过本次MIPS汇编程序设计的实验,我再次巩固了理论课所学习的程序代码的编写及书写规范,并将其付诸于实践。
同时,我也基本掌握了Qtspim软件的应用和程序的调试工作,并更深刻地理解了汇编语言中机器指令的执行方法,对以后的学习定会有莫大的帮助。
代码的编写过程,关键是先整理编写的思路,然后根据课本上的代码指令编写程序。
编译过程中,当然会遇到一些困难,但是通过思考和与老师同学的交流,都轻松解决了。
总的来说,本次实验做得还比较轻松,原理方面容易掌握,操作方面也容易实验。
望以后的实验也一样顺利。