Проанализируйте [закрытые] файлы C

В обычном соглашении о вызовах 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 
int sumargs(int n, ...) {
    va_list args;
    va_start(args, n);

    int sum=0;
    for (int i=0 ; i

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.

6
задан bhadra 17 November 2008 в 17:34
поделиться

7 ответов

Возможно, GNU project cflow http: / /www.gnu.org/software/cflow/?

0
ответ дан 8 December 2019 в 13:03
поделиться

Возможно излишество, но существует полный ANSI C синтаксический анализатор, записанный с Повышением. Дух: http://spirit.sourceforge.net/repository/applications/c.zip

Возможно, Вы сможете смоделировать его для удовлетворения потребностям.

3
ответ дан 8 December 2019 в 13:03
поделиться

Я не знаю, предлагает ли это библиотеку, но взгляните на CTAGS.

1
ответ дан 8 December 2019 в 13:03
поделиться

Если это - плоскость C, lex и yacc Ваши друзья, но необходимо взять препроцессор учетной записи C - исходные файлы с нерасширенными макросами обычно, не выполняют синтаксис C, таким образом, синтаксический анализатор, записанный с грамматикой K&R в памяти, скорее всего, перестанет работать.

Если Вы решаете проанализировать вывод препроцессора, подготовлены, что Ваш синтаксический анализатор перестанет работать из-за "расширений" Вашего конкретного компилятора, потому что вероятные стандартные заголовки библиотеки используют их. По крайней мере, это случай с GCC.

Я имел это с GCC и наконец решил достигнуть своей цели с помощью другого подхода. Если просто необходимо изменить имена для переменных, регулярные выражения сделают прекрасный, и нет никакой потребности создать полный синтаксический анализатор, по моему скромному мнению. Если Ваша цель состоит в том, чтобы только собрать данные, окончательный источник данных является отладочной информацией. Существуют способы вытащить отладочную информацию из двоичного файла - для исполняемых файлов ELF с КАРЛИКОМ существует libdwarf для земли Windows (COFF?) должно быть что-то также. Вероятно, можно использовать некоторые существующие инструменты для получения отладочной информации о двоичном файле - снова, я ничего не знаю о Windows, необходимо заняться расследованиями.

0
ответ дан 8 December 2019 в 13:03
поделиться

Недавно я прочитал о системе на основе win32, которая просматривала отладочную информацию в файлах DLL COFF: http://www.drizzle.com/~scottb/gdc/fubi-paper.htm

0
ответ дан 8 December 2019 в 13:03
поделиться

Анализировать C намного сложнее, чем кажется, когда вы принимаете учтите разные диалекты, директивы препроцессора, необходимость информации о типе при парсинге и т. д. Люди, которые говорят вам "просто используйте lex и yacc", имеют явно не производил синтаксический анализатор C.

Инструмент, который может это сделать, - это наш интерфейсный модуль C

Он решает все вышеперечисленные проблемы.

По завершении он имеет полную таблицу символов с возможностью навигации. со всеми идентификаторами и соответствующей информацией о типе. При этом перечисление глобальных и локальных переменных было бы тривиальным делом.

Я архитектор семантических дизайнов.

3
ответ дан 8 December 2019 в 13:03
поделиться
Другие вопросы по тегам:

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