Как мне сохранить или загрузить по байтам в память при использовании “riscv32-unknown-elf-gcc”?

#elf #riscv #riscv32

#elf #riscv #riscv32

Вопрос:

Я хочу управлять загрузкой памяти или сохранять в БАЙТАХ (8-бит) или ПОЛУСЛОВЕ (16-бит).

Итак, я создал код C, как показано ниже, и скомпилировал его, используя «riscv32-unknown-elf-gcc».

 void fun3 (void) {
    char i,j;
    i = (char)*(volatile unsigned int *) 0xf10007f8;
    j = (char)*(volatile unsigned int *) 0xf10007f4;
    *(volatile unsigned int *) 0xf10007f0 = (char) i j;
    *(volatile unsigned int *) 0xf10007fc = (int ) 0x4;
}
 

Я скомпилировал его следующим образом, и код функции de-asm выглядит следующим образом.

 riscv32-unknown-elf-gcc -march=rv32im -mabi=ilp32 -nostartfiles -nostdlib -Os   -x c  -Wl,-T,/work/test5.x -o test5.o test5.c
riscv32-unknown-elf-objdump -d -t test5.o > test5_Os.dump


f100006c <fun3>:
f100006c:   f1000737            lui a4,0xf1000
f1000070:   7f872783            lw  a5,2040(a4) # f10007f8 <__global_pointer$ 0xffffeef0>
f1000074:   7f472683            lw  a3,2036(a4)
f1000078:   0ff7f793            andi    a5,a5,255
f100007c:   0ff6f693            andi    a3,a3,255
f1000080:   00d787b3            add a5,a5,a3
f1000084:   7ef72823            sw  a5,2032(a4)
f1000088:   00400793            li  a5,4
f100008c:   7ef72e23            sw  a5,2044(a4)
f1000090:   00008067            ret
 

Я хочу преобразовать «lw» и «sw» в «lb» и «sb» в коде ассемблера выше.

Если вы знаете, пожалуйста, ответьте.

Ответ №1:

Если вы замените :

 i = (char)*(volatile unsigned int *) 0xf10007f8;
j = (char)*(volatile unsigned int *) 0xf10007f4;
*(volatile unsigned int *) 0xf10007f0 = (char) i j;
 

с помощью :

 i = *(char*) 0xf10007f8;
j = *(char*) 0xf10007f4;
*(char *) 0xf10007f0 = i j;
 

Компилятор сгенерирует загрузочные и сохраненные байты.
Дело в том, что в вашем коде вы говорите ему загрузить слово, потому что вы используете указатель unsigned int, и приведите результат к символу, чтобы он нормально использовал lw . То же самое для хранилища, вы используете указатель unsigned int.

Комментарии:

1. Спасибо за ваш ответ!! Код ассемблера был изменен следующим образом. «f100006c <fun3>:» «f100006c: f10007b7 lui a5,0xf1000» «f1000070: 7f87c703 lbu a4,2040(a5) # f10007f8 <__global_pointer$ 0xffffeef8>» «f1000074: 7f47c683 lbu a3,2036(a5)» «f1000078: 00d70733 добавить a4, a4,a3» «f100007c: 7ee78823 sb a4,2032 (a5)» «f1000080: 00400713 li a4,4» «f1000084: 7ee7ae23 sw a4,2044 (a5)» «f1000088: 00008067 ret»