Сборка x86, передающая параметры перед прыжком - PullRequest
1 голос
/ 15 октября 2019

Я работаю над старшим дизайнерским проектом и возвращаюсь в маленькую загадку. Есть ли какая-то ситуация, когда в сборке вы можете столкнуться с ситуацией, когда вы нажимаете параметры, затем делаете переход в другое место, затем вызываете функцию?

Не похоже, что вы можете из файлов, которые ядоступны для меня, но они не все включено. Любая помощь будет оценена, спасибо!

Ответы [ 2 ]

2 голосов
/ 15 октября 2019

Все, что имеет значение, это то, что находится в стеке, когда выполнение достигает вершины функции, которую вы хотите вызвать. Неважно, как или в каком порядке он туда попал, просто ESP указывает на адрес возврата, ESP+4 указывает на первый аргумент стека и т. Д.

Функция также не 'не знает или не заботится о том, достигли ли вы этого с call, или jmp хвостовым вызовом, или даже с jae условным хвостовым вызовом.

Вы даже не иметь для использования push вообще, вы можете sub esp, 24 в верхней части функции и просто использовать mov для хранения своих аргументов. (Как gcc -m32 -maccumulate-outgoing-args делает, что было хорошо на старых процессорах без стекового механизма, где push не был столь эффективен.) Почему gcc использует movl вместо push для передачи аргументов функции?

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


Поскольку вам даже приходилось задавать этот вопрос, помните, что ЦП по сути является конечным автоматом. Каждая инструкция имеет свое документированное влияние на архитектурное состояние (содержимое регистра и памяти, включая специальные регистры, такие как EFLAGS и указатель инструкции). Кроме этого, нет контекста. Неважно, как вы достигли состояния, только то, что вы находитесь в нем.


Контекст имеет значение для производительности для таких вещей, как задержки с частичной регистрацией, остановки пересылки в хранилище, прогноз ветвлений иобщий для дублирующего выполнения нескольких инструкций. Но не для корректности.

(я игнорирую эксплойты Spectre / Meltdown, которые создают известное микроархитектурное состояние, а затем считывают это в архитектурное состояние.)

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

Пример того, о чем вы говорите, может выглядеть так:

    cmp     al, 32

    push    48
    push    ecx
    push    esi
    jae     test

    call    func01
    jmp     done

test:
    call    func02

done:

Обе функции требуют трех одинаковых аргументов, но в зависимости от того, AL> = 32 определяет, какая функция вызывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...