【发布时间】:2019-10-15 00:48:02
【问题描述】:
我正在学习有关 RISC-V 组装的 Western Digital 教程。我对汇编编程比较陌生。所以我有一些澄清问题,我似乎找不到一个真正的虚拟友好教程。
这是有问题的代码on GITHub。
# SPDX-License-Identifier: Unlicense
# Copyright (c) 2018 Western Digital Corporation or its affiliates.
.section .text
.align 2
.globl setupGPIO
.include "memory_map.inc"
.include "gpio.inc"
setupGPIO:
addi sp, sp, -16 # Allocate Stack Frame
#First Question
sw ra, 12(sp) # Save return address onto the stack
li t0, GPIO_CTRL_ADDR # Load the base GPIO address
li t1, GPIO_RGB_PINS # Get the RGP Pins offset
sw t1, GPIO_OUTPUT_EN(t0) # Enable RGB pins as output pins
sw t1, GPIO_OUTPUT_XOR(t0) # Set the XOR to that the pins are Active High
#Second Question
sw x0, GPIO_OUTPUT_VAL(t0) # Set all writable GPIO pins to zero
#Third Question
lw ra, 12(sp) # Restore the return address
addi sp, sp, 16 # Deallocate stack frame
ret
所以,我的问题是:
12 在做什么?我认为堆栈指针已经在上一条指令中移动了 16 位。我通常对为什么在内存中向下移动 16 位,然后又添加 12 位感到困惑。
此外,这种语法在 x86 中是否与[eax+12]表达相同的意思?目标操作数一直在左边,这是否只针对
x0寄存器?我注意到我们根本没有使用堆栈指针,我们真的需要这样做吗?另外,
sw和lw有什么区别?它们都被使用过,我不确定它们完成了什么或者为什么会使用其中一个而不是另一个。
【问题讨论】:
-
我假设 sw 是“存储字”(将寄存器的值放入内存中,lw 是“加载字”(从内存中取出一个值并将其放入寄存器。
-
你所说的被移位了 16 位(实际上只是减去值 16,没有移位,而不是“位”(它的字节))是一种分配。请注意,在未分配的内存中存储到堆栈中是不好的形式(例如,堆栈指针下方是未分配的内存),因此通常分配先于使用。一旦分配了一些堆栈(这里是 16 个字节),新可用的位置就处于正偏移量。因此,新的 SP+12 在新分配的 16 字节堆栈空间内;由于该空间是正式分配的,因此即使其他人使用该堆栈,它也会保持保留。
-
@ErikEidt 但是为什么要掩盖 4 个字节呢?这仅仅是函数占用的空间量吗?