Size: a a a

Ассемблер

2021 August 23

К

Кролик in Ассемблер
привет всем
источник

К

Кролик in Ассемблер
хотел кое что уточнить: я правильно понимаю что при сдвиге вправо с sar значение самого старшего бита не изменяется?
источник

E

Entusiast in Ассемблер
Да
источник

К

Кролик in Ассемблер
пасеб)
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
#book в дополнение к другой книг
Профессиональное программированиена ассемблере x64 с расширениями AVX, AVX2 и AVX-512 Даниэль Куссвюрм
источник

D

Den in Ассемблер
Вот есть к примеру у тебя printf, и ты для него пушиш аргументв стек, свой текст например, так вот когда ты его пушишь esp автоматически сдвигается и если у тебя была какая то переменная к которой ты обращался по адресу esp то теперь она уехала в esp+4, потому что esp автоматически всегда на вершине стека, так вот если ты перед printf скопируешь esp в ebp то ты всегда сможешь обратиться к ebp и относительно него к локальным переменным той прошлой процедуры, той  которая была до printf, это типа такой снепшот, заморозка состояния esp, кроме того ты всегда сможешь почистить стек от использованых переменных  функций которые уже отработали вернувшись к тому состоянию, скопировав адрес ebp обратно в esp, это надо делать чтобы стек не пух иначе в итоге может крашнуться система, вообще для этого есть комманды call/ret enter/leave чтобы не делать этого вручную. Есть еще несколько стандартов неписания функций, они по разному работают со стеком, stdcall _cdecl fastcal, какие то чистят за собой стек какие то нет, т.е. ты должен будешь делать это сам тогда
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
чтоб относительно обновленного ebp, который получается из esp после загесения в стек аргументов и адреса возврата, можно так же было обращаться еще и килокальным переменным.

[ebp+...] это обращение к параметрам
[ebp-...] это обращение к локальным переменныи
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
источник

A

Aiwan ╭∩╮ (òÓ,) ╭∩╮b... in Ассемблер
источник

AP

Andrey P in Ассемблер
Перед тем как вызвать процедуру ты заносишь в стек параметры, когда вызываешь процедуру, call заносит в стек еще и адрес возврата. При каждом занесении чего то в стек, указатель вершины уменьшается. Поэтому, когда ты зашел в процедуру и спас ebx (тож в стеке),, а потом присвоил ему адрес вершины на этот момент, получается что все параметры находятся выше bp, а все, что еще наколотили в стек в процедуре будет ниже bp. Просто так через pop ты параметры не достанешь, так как там еще адрес возврата хранится. Как то так.
источник

E

Entusiast in Ассемблер
Проще:
call - заносит адрес возврата на данный указатель стэка ([esp]), а push:
sub esp, 4 ; или 8, и rsp
mov [esp], operand
Таким образом, стэк будет выглядеть так:

ESP = 0x400008
push eax ; ESP = 0x400004
(значение EAX находится на 0x400008)

call func  ; ESP = 0x400004

То есть, push положил значение EAX в 0x400008, и уменьшил указатель на 4, а call просто положил адрес возврата на данный указатель, он не уменьшал.
Таким образом, чтобы взять аргумент, нужно сделать [ESP+4], потому что на [ESP] будет адрес возврата.
А что делает pop:
mov operand, [esp]
add esp, 4 ; Или 8, и rsp
То есть, он возьмёт адрес из данного указателя на стэк, где лежит адрес возврата, а после чего увеличит ESP на 4, таким образом, ESP уже будет на +4, где нет никакого адреса возврата, вместо него там лежит наш параметр.

По-сути, взять параметр через pop - можно. Нужно сделать так:
add  esp, 4
pop  eax
sub  esp, 8
ret
То есть:
[ESP] -> Адрес возврата
[ESP+4] -> Параметр
После выполнения pop -> ESP будет стоять уже на +8, потому что он делает ещё один add esp, 4, поэтому его нужно вернуть на наш адрес возврата. Для x64 будет:
add  esp, 8
pop  eax
sub  esp, 16
ret

Но делать так не нужно, смысла от этого - ноль
источник

ВВ

Вячеслав Васютин... in Ассемблер
Офигеть... Спасибо Вам всем.
источник

AP

Andrey P in Ассемблер
По-сути, взять параметр через pop - можно. Нужно сделать так:
add  esp, 4
pop  eax
sub  esp, 8
ret

Это да) вопрос какой практический смысл? Манипуляций с памятью можно сделать много разных )
источник

d

disba1ancer in Ассемблер
Во втором асмолистинге ошибка тебе нужен sar
источник

E

Entusiast in Ассемблер
Проверял с любыми случайными значениями - нет никакой ошибки, работает
источник

d

disba1ancer in Ассемблер
Это интринсик, причём крайне неудобный, увы gcc не умеет в генерацию bsr
источник

d

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

E

Entusiast in Ассемблер
Да

0xF0001
0xE02
0xFFFFFF1
0x82918
0xFEFEFE
0xF0F0F0

Результат был:
0xF
0xE
0xF
0x8
0xF
0xF
источник

d

disba1ancer in Ассемблер
Тогда в сишном коде не используй инты или кастуй к беззнаковым, у тебя первый листинг, явно что-то шаманит со знаком
источник

A

Aleksandr in Ассемблер
Вроде бы с восьмой версии умеет
источник