MIPS组装功能,应该是结构(例如交换)
因此,我是MIPS组装的初学者,我知道如何使用LW,SW,ADDI等基本说明,但是我真的不明白它们如何共同形成单个功能。 如果说我想在MIPS中编写一个简单的交换功能,那么指令的顺序应该是什么,以便代码按预期工作?
关于如何编写函数是否有一般的“规则”?我首先要做什么,然后我该怎么办? 另外,计算机内存如何与寄存器相互作用?
正如我提到的交换,下面是我发现的一个示例,我不明白为什么每行对该功能都“有用”,尤其是在(我认为)存储矢量(?)的情况下(?
)有人可以解释第5-10行(从SLL开始),这确实会有所帮助。
很抱歉一次问这么多问题,我真的很困惑。
swap: #swap method
addi $sp, $sp, -12 # Make stack room for three
sw $a0, 0($sp) # Store a0
sw $a1, 4($sp) # Store a1
sw $a2, 8($sp) # store a2
sll $t1, $a1, 2 #t1 = 4a
add $t1, $a0, $t1 #t1 = arr + 4a
lw $s3, 0($t1) #s3 t = array[a]
sll $t2, $a2, 2 #t2 = 4b
add $t2, $a0, $t2 #t2 = arr + 4b
lw $s4, 0($t2) #s4 = arr[b]
sw $s4, 0($t1) #arr[a] = arr[b]
sw $s3, 0($t2) #arr[b] = t
addi $sp, $sp, 12 #Restoring the stack size
jr $ra #jump back to the caller
So I am a beginner in mips assembly and I know how to use the basic instructions such as lw,sw,addi etc but I can't really understand how these together can form a single function.
If let's say I want to write a simple swap function in mips, what should be the order of the instructions so that the code works as intended?
Is there a general "rule" about how a function should be written? What do I do first and then what do I do after that?
Also how does the computer memory interact with the registers?
and as I mentioned swap, below is an example I found, and in which I don't understand why each line is "useful" to the function, especially when it comes to (I think) storing the vector(?)
If at least someone could explain the lines 5-10 (starting from sll) that would really help.
Sorry for asking so many questions at once, I am just really confused.
swap: #swap method
addi $sp, $sp, -12 # Make stack room for three
sw $a0, 0($sp) # Store a0
sw $a1, 4($sp) # Store a1
sw $a2, 8($sp) # store a2
sll $t1, $a1, 2 #t1 = 4a
add $t1, $a0, $t1 #t1 = arr + 4a
lw $s3, 0($t1) #s3 t = array[a]
sll $t2, $a2, 2 #t2 = 4b
add $t2, $a0, $t2 #t2 = arr + 4b
lw $s4, 0($t2) #s4 = arr[b]
sw $s4, 0($t1) #arr[a] = arr[b]
sw $s3, 0($t2) #arr[b] = t
addi $sp, $sp, 12 #Restoring the stack size
jr $ra #jump back to the caller
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,大多数是 - 要在汇编中编写一个函数,我们写下:
必须遵循调用约定的规则,该规则是应用程序二进制接口ABI的一部分。
这些规则告诉我们:
。
这与 代码> $ a3 。
返回值以价值寄存器传递,
$ v0
,$ v1
。return noreferrer'>返回地址(或较旧的linkage)是一个指针参数,是一个告诉callee的地方返回以转到正确的呼叫者。 这是通往代码的指针,通常是指调用后立即引用呼叫者中的指令。  Callee希望在
$ ra
注册。 中找到此值。您永远不会在C中看到返回地址,但在组装中显示。堆栈指针提供堆栈存储空间,并且MIPS上的堆栈规则是:
就功能主体而言,如果您具有该功能的算法,则身体应遵循该算法。 如果该算法是用高级语言编写的,那么您应该知道每个结构化的(控制)语句,例如If-then,如果是else,则是elsse,while,while,因为是一种模式(表达嵌套的表达方式语句)在汇编语言中具有等效模式。 表达式相同:表达式可以分解为其零件部分并在机器代码中执行。
在机器代码级别,处理器提供物理存储。 这包括CPU寄存器和主要内存。 寄存器很快,直接在CPU内部,因此机器代码指令直接在其上进行操作。 主内存不在CPU之外,但广阔。 主内存是可寻址的,但CPU寄存器不是。 任何需要引用或索引的数据结构都必须存储在主内存中 - 这很好,因为确实没有足够的寄存器可以存储超过一个很小的数组。  nbsp;具有这些要求的数据结构包括:字符串,树,链接列表,阵列,因此在主内存中分配。
当我们使用时,还要注意代码存储在主内存中,这意味着机器代码程序的每个机器代码指令都有一个唯一的内存地址。 使用此属性,我们可以创建指代特定说明的指针,并且由返回地址的概念使用。
机器代码程序(无论是由汇编程序员编写,还是由编译器翻译),将数据从主存储器转移到寄存器,然后在MIPS上,使用负载和存储指令。 他们使用寄存器来完成计算,并使用主内存来存储数据结构。
此函数可分配堆栈空间并将参数存储在那里,但没有进一步使用该内存,因此这是浪费,但无害。  nbsp;该函数确实在返回之前归还分配的空间,鉴于首先分配了该函数(在这里确实不需要)。
以
SLL
进行数组索引。 他们使用$ s
登记簿违反了呼叫公约 - 这些寄存器被允许使用,但前提是在返回后保留其传入价值时,它们不是在这里,这是违规的。索引一个单词(
int
)数组需要操纵字节偏移。 单词数组的第一个元素是在地址,例如A,而在地址A+4处的第二个单词,因为第一个元素采用4个字节,每个字节也都有一个地址。 因此,索引一个单词数组的公式以a+i*4的形式给出,这就是代码正在做的。 它索引了两次(例如计算[i],a [j])的地址,从这些地址加载,然后将值存储回另一个地址,这是一个交换操作。这是C:我已经用常见的子表达消除表明的功能
,其中A [i]的地址计算和[J]的地址计算既可以读写和写入数组元素,否则就像在组装中所做的那样。
a
在$ a0
,i
中代码> $ a2 在函数输入时,根据调用约定,呼叫者将遵循哪个。Yes, mostly — to write a function in assembly, we write:
The function must follow the rules of the Calling Convention, which is part of the Application Binary Interface, ABI.
Those rules tell us:
For MIPS:
Parameters are passed in argument registers,
$a0
,$a1
,$a2
,$a3
.Return values are passed in value registers,
$v0
,$v1
.The return address (or by older term, linkage) is a pointer parameter that tells the callee where to return in order to go to the right caller. This is a pointer to code that generally refers to the instruction in the caller immediately after the call. The callee expects to find this value in the
$ra
register. You don't ever see the return address in C but is revealed in assembly.The stack pointer offers stack storage, and the rules of the stack on MIPS are:
As far as the function body is concerned, if you have an algorithm for the function, then the body should follow that algorithm. If the algorithm is written in a high level language, then you should know that every structured (control) statement, like if-then, if-then-else, while, do-while, for, is a pattern (of expressions an nested statements) that has an equivalent pattern in assembly language. The same for expressions: expressions can be decomposed into their piece parts and executed in machine code.
At the machine code level, the processor offers physical storage. This includes the CPU registers, and main memory. The registers are fast, directly inside the CPU and so machine code instruction directly operate on them. Main memory is outside the CPU but vast. Main memory is addressable but CPU registers are not. Any data structure that requires referencing or indexing must be stored in main memory — which is fine because there are really not enough registers to store more than a very small array. Data structures that have these requirements include: strings, trees, linked lists, arrays, so are allocated within main memory.
While we're at it, lets also note that code is stored in main memory, and that means that every machine code instruction of a machine code program has a unique memory address. Using this property, we can create pointers that refer to specific instructions, and that is used by the notion of the return address.
Machine code programs (whether written by assembly programmers, or translated by compilers), transfer data from main memory to registers and back — on MIPS, using load and store instructions. They use the registers to accomplish calculations, and main memory to store data structures.
This function allocates stack space and stores parameters there but doesn't make any use further use of that memory, so this is a waste, but harmless. The function does deallocate the allocated space before returning, as appropriate, given it allocated in the first place (which wasn't really needed here).
The lines starting with
sll
do array indexing. They use the$s
registers in violation of the calling convention — these registers are allowed to be used but only if their incoming values preserved upon return, which here they are not so that is the violation.Indexing a word (an
int
) array requires manipulating byte offsets. A first element of a word array is at address, A, for example, and a second word at address A+4, because the first element takes 4 bytes, each of which also has an address. So, the formula for indexing a word array is given as A+i*4, which is what that code is doing. It is indexing twice (e.g. computing the addresses for A[i], A[j]), loading from those addresses, and then storing back the values to where the other came from — which is a swap operation.Here is the function in C:
I have shown it with the common subexpression elimination where the address computation of A[i] and A[j] is used to both read and write the array elements, as has been done in the assembly.
A
is in$a0
,i
in$a1
, andj
in$a2
upon function entry, as per the calling convention, which callers will follow.