Объяснение кода Asm

Одна причина использовать reinterpret_cast состоит в том, когда базовый класс не имеет vtable, но производный класс делает. В этом случае, static_cast и reinterpret_cast приведет к различным значениям указателя (это было бы нетипичным случаем, упомянутым jalf выше ). Так же, как правовая оговорка я не заявляю, что это - часть стандарта, но реализация нескольких широко распространенных компиляторов.

Как пример, возьмите код ниже:

#include 

class A {
public:
    int i;
};

class B : public A {
public:
    virtual void func() {  }
};

int main()
{
    B b;
    const A* a = static_cast(&b);
    const A* ar = reinterpret_cast(&b);

    printf("&b = %p\n", &b);
    printf(" a = %p\n", a);
    printf("ar = %p\n", ar);
    printf("difference = %ld\n", (long int)(a - ar));

    return 0;
}

, Который производит что-то как:

& b = 0x7ffe10e68b38
= площадь 0x7ffe10e68b40
= различие 0x7ffe10e68b38
= 2

Во всех компиляторах я попробовал (MSVC 2015& 2017, лязгайте 8.0.0, gcc 9.2, ICC 19.0.1 - видят godbolt для последнего 3 ), результат эти static_cast отличается от результата reinterpret_cast 2 (4 для MSVC). Единственный компилятор для предупреждения о различии был лязгом, с:

17:16: предупреждение: 'reinterpret_cast' от класса 'B *' к его основе при ненулевом смещении '*' ведет себя по-другому по сравнению с 'static_cast' [-Wreinterpret-базовый-класс]
константа* площадь = reinterpret_cast (& b);
^ ~~~~~~~~~~~~~~~~~~~~~~~
17:16:примечание: используйте 'static_cast' для корректировки указателя правильно в то время как константа upcasting
* площадь = reinterpret_cast (& b);
^ ~~~~~~~~~~~~~~~
static_cast

Один последний протест состоит в том, что, если базовый класс не имеет никаких элементов данных (например, int i;) тогда, лязгают, gcc, и ICC возвращает тот же адрес для reinterpret_cast что касается static_cast, тогда как MSVC все еще не делает.

6
задан starblue 17 October 2009 в 08:17
поделиться

2 ответа

Мой ASM немного нечеткий в деталях, но я думаю, что могу дать вам общее представление.

ESP: указатель стека, EBP: указатель базы.

movl $1f, (%0)

Переместите значение 0x1f в параметр 0 (из).

movl %%esp, 4(%0)

Переместить содержимое регистра ESP в (из + 4).

movl %%ebp, 8(%0)

Переместить содержимое регистра EBP в (из + 8).

movl 8(%1), %%ebp

Переместить содержимое (в + 8) в регистр EBP.

movl 4(%1), %%esp

Переместить содержимое (в + 4) в регистр ESP.

jmp *(%1)

Перейти к адресу, содержащемуся в (в).

«1:» - это метка перехода.

«+ S» объявляет параметр «источник» (чтение), «+ D» - параметр назначения (запись). Список регистров в конце оператора - это список "clobber", список регистров, который может быть изменен кодом ASM, поэтому компилятор может предпринять шаги для поддержания согласованности (т. Е. Не полагаясь, например, на ECX все еще содержит то же значение, что и раньше).

Я предполагаю, что coco_ctx означает «контекст кокоса». Итак: функция сохраняет текущий кадр стека в структуре «от» и устанавливает для кадра стека то, что сохранено в структуре «до». По сути, он переходит из текущей функции в другую.

10
ответ дан 9 December 2019 в 20:46
поделиться

DevSolar дает правильный ответ - я просто добавлю, что вы можете узнать немного больше о том, что такое EBP и ESP для здесь.

2
ответ дан 9 December 2019 в 20:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: