Borland x86 встроенный ассемблер; получить адрес этикетки? - PullRequest
8 голосов
/ 16 октября 2008

Я использую Borland Turbo C ++ с некоторым встроенным ассемблерным кодом, так что, вероятно, ассемблерный код в стиле Turbo Assembler (TASM). Я хочу сделать следующее:

void foo::bar( void )
{
    __asm
    {
      mov eax, SomeLabel
      // ...
    }
    // ...
SomeLabel:
    // ...
}

Таким образом, адрес SomeLabel помещается в EAX. Это не работает, и компилятор жалуется на: неопределенный символ 'SomeLabel'.

В Microsoft Assembler (MASM) символ доллара ($) служит текущим счетчиком местоположения, что было бы полезно для моей цели. Но, опять же, это не работает в Borlands Assember (синтаксическая ошибка выражения).

Обновление: чтобы быть более конкретным, мне нужен компилятор для генерации адреса, который он перемещает в eax как константу во время компиляции / компоновки, а не во время выполнения, поэтому он будет компилироваться как "mov eax, 0x00401234".

Кто-нибудь может подсказать, как заставить это работать?

ОБНОВЛЕНИЕ: Чтобы ответить на вопрос Пакса (см. Комментарий), если базовый адрес изменяется во время выполнения загрузчиком Windows, образ DLL / EXE PE по-прежнему будет перемещаться загрузчиком Windows, а адрес меток будет исправлен в время выполнения загрузчиком для использования переопределенного адреса, поэтому использование значения времени компиляции / ссылки для адреса метки не является проблемой.

Большое спасибо заранее.

Ответы [ 12 ]

0 голосов
/ 16 октября 2008

Я не знаю конкретно о вашем компиляторе / ассемблере, но хитрость, которую я использовал довольно часто, заключается в том, чтобы вызвать следующую локацию и затем вставить стек в ваш регистр. Удостоверьтесь, что сделанный вами звонок только выдвигает обратный адрес.

0 голосов
/ 16 октября 2008

Насколько я помню, вы не можете использовать внешнюю (C ++) метку в вашей встроенной сборке, хотя у вас могут быть метки в стиле TASM в блоке asm, на которые могут ссылаться сами инструкции сборки. Я думаю, что использовал бы флаг и оператор переключения после ассемблера для обработки ветвления. Например:

int result=0;

__asm__ {
    mov result, 1
}

switch (result){
    case 1:  printf("You wanted case 1 to happen in your assembler\n"); break;
    case 0:  printf("Nothing changed with the result variable.. defaulting to:\n");
    default: printf("Default case!\n"); break;
}
...