The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Индекс форумов
Составление сообщения

Исходное сообщение
"Выпуск языка программирования Rust 1.43"
Отправлено Ordu, 26-Апр-20 18:55 
> Перед ret тебе как минимум надо будет pop-ить
> несколько регистров которые ты использовал в функции а это зачастую может
> повлиять на флаг переполнения.

Нет, не может. Содержимое идущее в регистр из стека не меняет флагов. Изменение %rsp командой pop тоже не меняет CF, хотя %rsp при этом и меняется посредством сложения. Единственный способ изменить флаги из стека -- это popf.

А, хотя не, есть ещё iret.

> А чушь которую ты напишешь дальше -
> что типа ты stc будешь ПРОВЕРЯТЬ и Выставлять сразу перед ret
> я даже обсуждать не хочу - данных вычислений уже акутальных в
> регистрах не будет. Там будут pushеные в начале функции значения.

Всякие разные конвенции вызова, часто не гарантируют сохранность _всех_ регистров. Даже более того, они _все_ не гарантируют сохранность _всех_ регистров, потому что как минимум один из них используется под возвращаемое значение. Но я к тому, что часто бывают ещё и другие регистры, которые не сохраняются. Но даже если бы это было не так, то никто не помешал бы мне сделать что-то типа:

   ; бла-бла-бла,
   ; кладём в %rax возвращаемое значение
   add $N, %rsp ; снимаем к чертям локальные переменные со стека
           ; оставляя пока себе локальные значения регистров, которые нам ещё понадобяться
   <тут проверка на ошибку, которая для более показательной сложности не CF выставляет, а ZF>
   pop %<saved-reg> ; восстанавливаем регистры, повторяя это для каждого сохранённого регистра
   jz 1f ; если ошибка приключилась
   clc
   ret
1:
   stc
   ret

Заметь: если мне удастся провести проверку на ошибку так, чтобы CF заполнился бы этой ошибкой как надо, то и гнусный условный переход не понадобиться. И это вполне возможно будет именно так, потому как есть всякие арифметические команды, которые выполняются _условно_, если флаги правильно проставлены.

Например, хочется мне сделать сисколл, который возвращает неотрицательный int, в случае успеха, и отрицательный int в случае ошибки (то есть -errno) -- это довольно распространённо при вызове сисколлов в лине. Но мне хочется вернуть в любом случае неотрицательное значение, которое будет сопровождаться CF, чтобы вызывающий код понял, ошибка это или нет, тогда:

   ; бла-бла-бла
   syscall
   test $0, %rax
   clc
   jns  1f
   neg %rax
   stc
1:
   pop <все те регистры, которые испортил syscall, и которые мы не должны портить>
   ret

Только чтобы конвеер не сбивать в случае, когда всё идёт хорошо, лучше всё от 1: и до ret перенести куда-нибудь выше по коду, дабы переход случался назад. И я вот думаю, что практически наверняка есть какой-нибудь хитрый способ проверить %rax на отрицательность, который заполнит нам CF так как надо, но неохота думать.

> И да, не надо мне щас лапшу вешать что ты настолько крут
> что с 12 регистрами общего назначения сможешь без стека обойтись -
> не стоит.

Эмм... Не хочу тебя огорчать, но у меня всегда было плохо с арифметикой, и ещё в досовские времена я ненавидел работать с переменными на стеке, потому что для этого надо было считать их смещение от того значения sp которое было на входе в функцию. Кроме того, мне кошмарно не нравилось занимать целый регистр адресом стекового фрейма, а если не занимать, то в 16-битном режиме было невозможно было косвенно адресовать память через sp. Поэтому у меня выработалась гнусная привычка писать под _стековую_ машину, ну то есть я жонглирую регистрами, а когда мне их не хватает, я делаю push, потом, когда появляется свободный регистр, извлекаю значение обратно при помощи pop. Такие интересные эффекты случаются, когда случается вписать в цикл несбалансированное количество push/pop -- это просто нечто. Хотя, в досе, как правило это кончалось наглухо висящей машиной.

Дурацкая привычка, я не спорю, единственный бонус -- компактность кода, которая бонусом могла быть разве что в 16-битном досе. Но, как бы там ни было, на amd64 есть _КУЧА_ регистров, и тут гораздо проще обходиться без адресации в глубины стека.

 

Ваше сообщение
Имя*:
EMail:
Для отправки ответов на email укажите знак ! перед адресом, например, !user@host.ru (!! - не показывать email).
Более тонкая настройка отправки ответов производится в профиле зарегистрированного участника форума.
Заголовок*:
Сообщение*:
 
При общении не допускается: неуважительное отношение к собеседнику, хамство, унизительное обращение, ненормативная лексика, переход на личности, агрессивное поведение, обесценивание собеседника, провоцирование флейма голословными и заведомо ложными заявлениями. Не отвечайте на сообщения, явно нарушающие правила - удаляются не только сами нарушения, но и все ответы на них. Лог модерирования.



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру