Как передать переменные во внешнюю функцию сборки - PullRequest
0 голосов
/ 18 октября 2019

Как передать переменную из программы на C в функцию сборки.

Пример:

main.c:

void main() {
  unsigned int passthis = 42
  extern asm_function();
  asm_function(passthis)
}

main.asm:

bits 32
global start
section .text
asm_function:
  ...

Как мне получить доступ к passthis в asm_function.

Редактировать: Вероятно, следовало бы упомянуть, что я не использую ОС, я компилирую с использованием кросса i686-elfкомпилятор и собираюсь использовать его как ядро.

Ответы [ 2 ]

3 голосов
/ 18 октября 2019

Если вы компилируете C в 32-битный код с параметрами GCC по умолчанию (не -mregparm=3, как использует ядро ​​Linux), то при вводе функции первый аргумент находится в стеке чуть выше адреса возврата (в * 1002). *), но это смещение изменяется после push чего-либо или перемещения ESP.

Вы можете использовать [ebp+8] после установки традиционного указателя стека (который не изменяется во время функции, даже когда ESP делает).

Например, int asm_function(int) может быть реализовано как:

;bits 32              ; unneeded, nasm -felf32 implies this.
global asm_function   ; include asm_function in ELF .o symbol table for linking
section .text
asm_function:
    push ebp
    mov ebp, esp
    mov eax, [ebp+8]  ; return the first argument
    mov esp, ebp
    pop ebp
    ret

Для каждого параметра после этого просто добавьте еще один 4 (то есть для второго параметра используйте [ebp+12]). Как вы можете видеть, установка EBP в качестве указателя кадра добавляет много накладных расходов для крошечных функций.

В некоторых не-ELF системах / ABI перед символами C ставится начальный знак подчеркивания, поэтому вы должны объявить оба asm_function и _asm_function чтобы ваш код был примерно эквивалентен для этих ABI, например:

global _asm_function
global asm_function  ; make both names of the function global
section .text
_asm_function:
asm_function:        ; make both symbols point to the same place
    push ebp
    mov ebp, esp
    mov eax, [ebp+8]
    mov esp, ebp
    pop ebp
    ret
2 голосов
/ 18 октября 2019

x86 имеет, вероятно, несколько различных соглашений о вызовах. Это зависит от ряда факторов, таких как Windows и Linux, и от того, какую среду компилятора вы используете, 32-битной и 64-битной и т. Д.

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

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

...