Функция с неопределенным числом аргументов MIPS

Если вам нужен доступ ко всей файловой системе на клиенте, чтение / запись файлов, просмотр папок для изменений, запуск приложений, шифрование или подписывание документов и т. д., пожалуйста, посмотрите на JSFS.

Это позволяет безопасный и неограниченный доступ с вашей веб-страницы к ресурсам компьютера на клиенте без использования технологии плагина браузера, такой как AcitveX или Java Applet. Тем не менее, мир программного обеспечения также должен быть установлен.

Для работы с JSFS вы должны иметь базовые знания в разработке Java и Java EE (сервлеты).

Пожалуйста, найдите JSFS здесь: https://github.com/jsfsproject/jsfs . Это бесплатно и лицензировано в GPL

0
задан Michael 19 January 2019 в 12:18
поделиться

1 ответ

В обычном соглашении о вызовах MIPS, аргументы после 4-го уже будут храниться в стеке вызовов, помещенном там вашим вызывающим абонентом.

Стандартное соглашение о вызовах оставляет заполнение перед аргументами стека, где вы можете хранить аргументы регистров для создания непрерывного массива всех аргументов. Этот PDF-файл содержит диаграмму , а также см. вызов функции MIPS с более чем четырьмя аргументами

Обычно это называется «теневым пространством» в Windows x86-64. Но поскольку MIPS jal ничего не сохраняет в памяти (в отличие от x86, который помещает адрес возврата в стек, MIPS помещает адрес возврата в $lr), даже если соглашение о вызовах не включает это теневое пространство в функцию все еще можно сначала настроить SP, а затем сохранить аргументы регистров, смежные с аргументами стека. Таким образом, единственное преимущество, которое я могу видеть, это дать крошечным функциям дополнительное пространство для нуля без необходимости настройки указателя стека. Это менее полезно, чем в x86-64, где без него невозможно легко создать массив аргументов.


Или вы можете очистить первые 3 итерации суммы, которые обрабатывают $a1 .. $a3 (опять-таки, предполагая стандартное соглашение о вызовах MIPS с первыми 4 аргументами в регистрах, $a0 - int n).

Затем переберите аргументы стека, если вы еще не достигли n.


Вы можете написать функцию C и посмотреть на оптимизированный вывод компилятора, например, что

#include <stdarg.h>
int sumargs(int n, ...) {
    va_list args;
    va_start(args, n);

    int sum=0;
    for (int i=0 ; i<n ; i++){
        sum += va_arg(args, int);
    }
    va_end(args);
    return sum;
}

va_start и va_arg не являются реальными функциями; они расширятся до некоторого встроенного кода. va_start(args,n) сбрасывает регистры передачи аргументов после n в теневое пространство (смежное с аргументами стека, если есть).

MIPS gcc, к сожалению, не поддерживает опцию -mregnames для использования имен, таких как $ a0 и $ t0, но Google нашел хорошую таблицу с именем регистра < -> number

Вывод MIPS asm из проводника компилятора Godbolt

# gcc5.4 -O3 -fno-delayed-branch  
sumargs(int, ...):
      # on entry: SP points 16 bytes below the first non-register arg, if there is one.
        addiu   $sp,$sp,-16  # reserve another 16 bytes
        addiu   $3,$sp,20    # create a pointer to the base of this array
        sw      $5,20($sp)   # dump $a1..$a3 into the shadow space
        sw      $6,24($sp)
        sw      $7,28($sp)    
        sw      $3,8($sp)    # spill the pointer into scratch space for some reason?
        blez    $4,$L4       # check if the loop should run 0 times.
        nop                  # branch-delay slot.  (MARS can simulate a MIPS without delayed branches, so I told gcc to fill the slots with nops)

        move    $5,[111]        # i=0
        move    $2,[111]        # $v0 = sum = 0
$L3:                         # do {
        lw      $6,0($3)
        addiu   $5,$5,1        # i++
        addu    $2,$2,$6       # sum += *arg_pointer
        addiu   $3,$3,4        # arg_pointer++  (4 bytes)
        bne     $4,$5,$L3    # } while(i != n)
        nop                  # fill the branch-delay slot

$L2:
        addiu   $sp,$sp,16
        j       $31          # return (with sum in $v0)
        nop

$L4:
        move    $2,[111]                     # return 0
        b       $L2
        nop

Зацикливание на do {}while(--n) было бы более эффективным. Это пропущенная оптимизация, что gcc не делает этого при компиляции цикла for.

0
ответ дан Peter Cordes 19 January 2019 в 12:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: