Сборка IA32: инструкция
Я знаю, что предложение, которое я собираюсь сказать, является, вероятно, лучшим способом стать очень непопулярным в Stackru очень быстро. Я все равно скажу: почему это не работает (полностью)?
Я пытался выяснить, что делает инструкция по отбору / обучению. Как я понимаю, lea / leal узнает адрес памяти первого операнда и записывает этот адрес во второй операнд (который может быть регистром или около того).
Эта часть, кажется, работает. Когда я запускаю программу ниже, она говорит:
The memory address of var is 134518204.
Однако сразу после этого написано что-то вроде "ошибки доступа к памяти". pushl (% eax), очевидно, не работает. Почему бы и нет?
.data
var: .long 42
str1: .string "The memory address of var is %d.\n"
str2: .string "At this memory address we find var's value: %d.\n"
.text
.global main
main:
leal var, %eax # Copy the address of var into %eax
pushl %eax
pushl $str1
call printf # Print str1
pushl (%eax)
pushl $str2
call printf # Print str2
# Some stack cleaning should be here :)
movl $1, %eax
int $0x80
Я даже не уверен, правильно ли я понял, что делает Леа / Лил. Помощь приветствуется.;)
2 ответа
Как я понимаю, lea/leal узнает адрес памяти первого операнда и записывает этот адрес во второй операнд (который может быть регистром или около того).
Звучит достаточно точно. Используется для выполнения адресной арифметики; это может быть так же просто, как просто загрузить адрес, но вы также можете использовать его для выполнения умножения на определенные константы.
pushl (%eax)
очевидно не работает. Почему бы и нет?
Ваш push
инструкция не ссылается на адрес, который вы думаете, что он делает: printf
возвращает количество написанных символов, и это значение возвращается в %eax
зарегистрироваться, так %eax
больше не содержит адрес var
,
lea
обычно (ab) используется для вычислений: если вы просто хотите адрес глобального в регистре, movl $var, %eax
является более четким (и байтом короче), чем lea
,
Кроме того, чтобы было понятно, целевой операнд lea
должен быть регистр.