#assembly #x86
#сборка #x86
Вопрос:
Итак, если у меня есть процедура, в которой первым формальным параметром является int[]
, и я выполняю перечисление через этот цикл, я не понимаю, почему один фрагмент кода работает, а другой нет. Я должен быть в состоянии сделать это:
#where ebp 8 is the location of the pointer, and ecx is the counter
mov edx, [ebp ecx*4 8]
Это дает мне бессмысленное значение для edx, но этот код работает нормально
mov edx, [ebp 8]
mov edx, [edx ecx*4]
Я не понимаю разницы между этими утверждениями.
Комментарии:
1. Должно быть, я старею. Я не помню ни одного
ecx*4
на ассемблере x86.2. @JohnSaunders: Вы забываете о байте SIB (конечно, это также описано в руководствах Intel).
3. Спасибо за ссылку. Я этого не забыл. Я перестал работать с ассемблером x86 до появления 64-разрядных процессоров.
4. @JohnSaunders: Это работает на всех процессорах, совместимых с i386 (хотя ссылка может заставить вас поверить в обратное). Даже если вы не часто кодируете ассемблер вручную, вы, вероятно, видели их в дизассемблировании, где такие вещи, как
lea eax, [eax eax*4]
являются общими дляeax *= 5
.5. Ах, извините, я не понял, сколько вам лет sk00l :). Если вы хотите сохранить здравомыслие, я предлагаю вам никогда не заглядывать в то, как последние коды операций кодируются на x86 (3-байтовые коды операций? проверьте. обязательные префиксы, определяющие инструкцию? проверьте ).
Ответ №1:
Они разные:
В первом коде:
mov edx, [ebp ecx*4 8]
Загрузка выполняется с адреса: ebp ecx*4 8
Во втором коде:
mov edx, [ebp 8]
mov edx, [edx ecx*4]
Сначала вы загружаете значение, сохраненное в ebp 8
. Затем вы используете его в качестве базового адреса для второй загрузки.
Другими словами, базовый адрес хранится в ячейке памяти, на которую указывает ebp 8
. На самом деле это не хранится в ebp
самом регистре.
Комментарии:
1. На «C». Первое является
edx = ebp[ecx 2]
, а второе —edx = (ebp[2])[ecx]
.