Size: a a a

Ассемблер

2021 August 30

Q

Qqqq in Ассемблер
все , не душу, лучше пойду перечитаю )
источник

E

Entusiast in Ассемблер
Ты делаешь что-то с регистрами:
mov ebx, 2
add  ebx, ecx
jc ...
Потом ты вызываешь какую-то функцию, она возвращает результат в EAX:
call some_func

Она не сохраняет регистры, и делает что-то с EBX и ECX:
some_func:
...
xor ebx, ebx
mov ecx, ebx
...
ret

После того, как фунцкия вернётся, ты продолжаешь работать с регистрами:
add ebx, ecx

А вот беда - функция не сделала:
push ebx
push ecx
...
xor ebx, ebx
mov ecx, ebx
...
pop ecx
pop ebx
ret

Поэтому теперь в ECX и EBX у тебя нули, и всё сломалось.
источник

Q

Qqqq in Ассемблер
Да но перед тем как ее вызвать мы пушим значения регистров в стек
источник

Q

Qqqq in Ассемблер
Если хотим сохранить что-то
источник

E

Entusiast in Ассемблер
Это ужасное решение.

Подобного рода код:

push eax
push ebx
push ecx
push data ; arg3
push ecx ; arg2
push 1 ; arg1
call func
pop ecx
pop ebx
pop eax

Как думаешь, красивый? Хотя, сколько не некрасивый, а неудобный (ну и неоптимизированный). Поэтому все пришли к выводу, что намного удобнее, и лушче - переносить сохранение регистров внутрь функции
К тому же - а откуда ты знаешь, какие регистры будет использовать функция? Допустим, если это из плохо документированной библиотеки. Будешь в дизассемблере копаться? Это неудобно для всех, об этом должен позаботиться разработчик функции
источник

Q

Qqqq in Ассемблер
Извиняюсь за глупые вопросы...
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
proc some_func uses ecx ebx, param1,....

я обычно так делаю и не замарачиваюсь
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
но эт палка о двух концах. с одной стороны надо знать что делает этот uses, а с другой - понимать зачем именно тебе это использовать в той или иной ситуации
источник

Q

Qqqq in Ассемблер
Мне пока сложно рассуждать об оптимизациях , понять бы банальные вещи...
источник

E

Entusiast in Ассемблер
Ну вот - отредактировал сообщение, добавив банальную вещь.

Вот есть у тебя, к примеру, тот же WinAPI. Если бы он не сохранял регистры - откуда ты знаешь, изменяет ли он тот или иной регистр? Копаться теперь в дизассемблере каждой библиотеки? А потому что сохранять все регистры в стэк подряд - решение не очень. Вот и снова вывод - нужно, чтобы об этом позаботился сам разработчик библиотеки\кода.
Закинешь ты:
push ebx
push ecx
push esi
push edi

А на деле окажется, что функция изменяет только один EBX, вот и потратил скорость и размер на лишние push/pop
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
даешь анархию, пишим говнокод 👻
источник

II

Ira Irina in Ассемблер
жалко в x86, нет двух наборов регистров, как в z80. Удобно было бы переключаться между ними при входе в функцию и при выходе.
источник

d

disba1ancer in Ассемблер
Если в отладочном билде то не удивительно
источник

楽園松本 in Ассемблер
Напиши макрос, засовывай в стек
источник

d

disba1ancer in Ассемблер
Кто сказал что нельзя? А флаги компиляции зачем?
источник

E

Entusiast in Ассемблер
Я об этом тоже писал. Есть флаг PIC
источник

d

disba1ancer in Ассемблер
Что касается регистров, то это просто соглашение
источник

Q

Qqqq in Ассемблер
Приблизительно это я и хотел уточнить , ибо пишут ,что для надобности можно сохранить в стек и потом восстановить значение . В промежутки между этим можно пользоваться всеми шестью регистрами
источник

E

Entusiast in Ассемблер
А если уйти вообще от соглашений, есть способ сохранить нормально регистры, после вызова функции?
источник

d

disba1ancer in Ассемблер
Без них никак, боюсь
источник