Ассемблерная команда LEA

463
04 января 2017, 02:52

Не знаю почему, но эта ассемблерная команда не дает мне покоя LEA.

C++

int f(int t)
{
  return t+1;
}
int f(int*t)
{ 
  return *t+1;
}
int f(int& t)
{
  return t+1;
}

Ассемблер

f(int):                                  # @f(int)
        lea     eax, [rdi + 1]
        ret
f(int*):                                 # @f(int*)
        mov     eax, dword ptr [rdi]
        inc     eax
        ret
f(int&):                                 # @f(int&)
        mov     eax, dword ptr [rdi]
        inc     eax
        ret

Если команда MOV ясна как день, то команда LEA не ясна!

Я знаю что команда LEA выполняет вычисление адреса второго операнда и записывание его в первый операнд (это все что мне известно)

В том примере что по ссылке, а именно: lea eax,[rdi + 1] это явно не вычисление адреса и не запись в первый операнд, нет запись то будет но скорее всего что-то другое. Или я что-то не правильно понял? Объясните пожалуйста в соответствии с С++ кодом.

P.S Искал, но исчерпывающего ответа на мой вопрос не нашел, искал даже в книжке Калашникова, а там даже этой команды не нашел...эхх.

Answer 1

Эта команда загружает в eax адрес того, что справа - т.е. rdi+1. Такой хитрый способ объединить

mov  eax, rdi
inc  eax

Т.е. в каком-то смысле в переводе на C++ это

&*(rdi+1)

:) Т.е. получение адреса объекта, находящегося по адресу [rdi+1].

См., например, тут.

Answer 2

Данная команда

    lea eax,[rdi + 1]

заносит в регистр eax значение rdi + 1, где в rdi хранится значение аргумента.

В двух остальных случаях, когда аргумент передается по ссылке или передается указатель на исходный аргумент, то регистр rdi содержит адрес аргумента.

    f(int*):                                 # @f(int*)
            mov     eax, dword ptr [rdi]
            inc     eax
            ret
    f(int&):                                 # @f(int&)
            mov     eax, dword ptr [rdi]
            inc     eax
            ret

Поэтому сначала в регистр eax заносится значение аргумента, используя тот адрес, который находится в rdi

            mov     eax, dword ptr [rdi]

а затем значение регистра eax увеличивается на 1.

            inc     eax

То есть различие между первым определением функции и двумя последующими состоит в том, что в первом случае регистр rdi содержит копию значения аргумента, тогда как в двух последних случаях регистр rdi получает адрес исходного аргумента.

READ ALSO
подсчет количества

подсчет количества

link: default null, но значение notNULLСтруктура таблиц, значение по умолчанию

602
Поиск пропавших дуг для полного графа

Поиск пропавших дуг для полного графа

Дана таблица в которой перечислены все дуги связного ориентированного графаВ таблице два числовых поля, в первом указана начальная вершина...

465
Как осуществить скроллинг с блоками?

Как осуществить скроллинг с блоками?

Вот, к примеру, есть всего 10 достаточно больших блоков с каким-либо фоном, которые не умещаются на экранеВ строке по 2 таких блока

479
Jsoup с одними сайтами работает, с другими - нет

Jsoup с одними сайтами работает, с другими - нет

Здравствуйте! Стал интересен парсинг html-страниц, начал разбираться с Jsoup, почитал несколько довольно стареньких гайдов по этому поводу(там...

674