Что делают эти коды операций? - PullRequest
1 голос
/ 15 октября 2019

Я работаю над учебным пособием по Western Digital для сборки RISC-V. Я относительно новичок в программировании на ассемблере. Итак, у меня есть несколько уточняющих вопросов, и я не могу найти настоящий тупой дружественный учебник.

Вот код вопроса на 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. Я заметил, что мы вообще не использовали указатель стека,нам действительно нужно сделать все это? Кроме того, в чем разница между sw и lw? Они оба были использованы, и я не уверен, что они достигают или почему один будет использоваться над другим.

1 Ответ

1 голос
/ 16 октября 2019

1) вычитание 16 из указателя стека резервирует место в стеке для текущего кадра. Чтобы сохранить вещи в этом зарезервированном пространстве, вы добавляете смещение (в данном случае 12) к указателю уменьшенного стека.

2) sw хранит слово (в данном случае значение 0, которое x0всегда содержит) из регистра в память, и вы правы (IMO), что порядок аргументов выглядит обратным по сравнению с остальной частью синтаксиса.

3) a) мы использовали указатель стека длясохранить и восстановить адрес возврата, который в этой небольшой функции, которая сама по себе не выполняет вызов, не нужен, но в качестве стандартного шаблона для входа и выхода из функции это полезный шаблон. Стек используется для хранения локальных переменных, которые не помещаются в регистры (или должны быть в стеке для поддержки рекурсии), и изучение того, как с ним работать, является частью того, что они показывают вам здесь.

3 b) sw сохраняет значение из регистра в памяти, а lw загружает из памяти и сохраняет в регистре. В драйвере устройства места памяти - это то, как вы взаимодействуете с устройством. Хранение в памяти позволяет передавать на устройство информацию (данные или управляющую информацию), а загрузка из памяти - это способ чтения информации с устройства.

...