【问题标题】:What do these Opcodes do?这些操作码有什么作用?
【发布时间】: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

所以,我的问题是:

  1. 12 在做什么?我认为堆栈指针已经在上一条指令中移动了 16 位。我通常对为什么在内存中向下移动 16 位,然后又添加 12 位感到困惑。
    此外,这种语法在 x86 中是否与 [eax+12] 表达相同的意思?

  2. 目标操作数一直在左边,这是否只针对x0寄存器?

  3. 我注意到我们根本没有使用堆栈指针,我们真的需要这样做吗?另外,swlw 有什么区别?它们都被使用过,我不确定它们完成了什么或者为什么会使用其中一个而不是另一个。

【问题讨论】:

  • 我假设 sw 是“存储字”(将寄存器的值放入内存中,lw 是“加载字”(从内存中取出一个值并将其放入寄存器。
  • 你所说的被移位了 16 位(实际上只是减去值 16,没有移位,而不是“位”(它的字节))是一种分配。请注意,在未分配的内存中存储到堆栈中是不好的形式(例如,堆栈指针下方是未分配的内存),因此通常分配先于使用。一旦分配了一些堆栈(这里是 16 个字节),新可用的位置就处于正偏移量。因此,新的 SP+12 在新分配的 16 字节堆栈空间内;由于该空间是正式分配的,因此即使其他人使用该堆栈,它也会保持保留。
  • @ErikEidt 但是为什么要掩盖 4 个字节呢?这仅仅是函数占用的空间量吗?

标签: assembly riscv opcode


【解决方案1】:

1) 从堆栈指针中减去 16,为当前帧保留堆栈空间。为了将内容存储到该保留空间中,您需要向递减的堆栈指针添加一个偏移量(在本例中为 12)。

2) sw 将一个单词(在本例中为值 0,x0 始终包含)从寄存器存储到内存,你是对的(IMO),与其余参数相比,参数的顺序向后看语法。

3) a) 我们使用堆栈指针来保存和恢复返回地址,在这个本身不进行调用的小函数中不需要它,而是作为函数进入和退出的标准样板,这是一个有用的模式。堆栈用于存储不适合寄存器的局部变量(或需要在堆栈上以支持递归),学习如何使用它是他们在这里向您展示的内容的一部分。

3 b) sw 将寄存器中的值存储到内存中,lw 从内存中加载并存储到寄存器中。在设备驱动程序中,内存位置是您与设备通信的方式 - 存储到内存可让您向设备提供信息(数据或控制信息),从内存加载是您从设备读取信息的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 2010-11-28
    • 2015-07-04
    • 2011-12-31
    相关资源
    最近更新 更多