Borland x86 встроила ассемблер; получить адрес маркировки?

Вы должны проверить информацию о вашем ПК и, соответственно, требуемый тензорный поток для установки и проверить шаги на этом сайте тензорного потока https://www.tensorflow.org/install/pip

8
задан Johan - reinstate Monica 10 June 2014 в 14:08
поделиться

10 ответов

В прошлый раз, когда я пытался сделать некоторый ассемблерный код совместимым с Borland, я столкнулся с ограничением, что Вы не можете маркировки ссылки вперед. Не уверенный, если это - то, с чем Вы сталкиваетесь здесь.

4
ответ дан 5 December 2019 в 15:28
поделиться

Все, что я могу найти о Borland, предлагает, чтобы это должно было работать. Подобные вопросы на других сайтах (здесь и здесь) предполагают, что Borland может обработать ссылки вперед для маркировок, но настаивает на маркировках, являющихся снаружи asm блоки. Однако, поскольку Ваша маркировка уже была вне asm блока...

Мне любопытно, позволил ли Ваш компилятор Вам использовать эту маркировку в, например, jmp инструкция. Играя вокруг с ним (по общему признанию, на совершенно другом компиляторе), я нашел, что противная тенденция для компилятора жаловалась на типы операнда.

Синтаксис очень отличается, и это - моя первая попытка встроенного asm в долгое время, но я полагаю, что портил это достаточно для работы под gcc. Возможно, несмотря на различия, это могло бы быть несколько полезно Вам:

#include <stdio.h>
int main()
{
    void *too = &&SomeLabel;
    unsigned int out;
    asm
    (
      "movl %0, %%eax;"
      :"=a"(out)
      :"r"(&&SomeLabel)
    );
SomeLabel:
    printf("Result: %p %x\n", too, out);

    return 0;
}

Это генерирует:

...
        movl    $.L2, %eax
...
.L2:

&& оператор является нестандартным расширением, я не ожидал бы, что это будет работать где угодно кроме gcc. Надо надеяться, это, возможно, вызвало некоторые новые идеи... Удачи!

Править: Хотя это перечислено как конкретная Microsoft, вот другой экземпляр перехода к маркировкам.

4
ответ дан 5 December 2019 в 15:28
поделиться

3 предложения:

1) поместите '_' перед SomeLabel в блоке, таким образом, это становится "mov eax, _SomeLabel". Обычно компилятор будет добавлять тот, когда он переведет C в блок.

Или

2) поместите маркировку в участок сборки. Это будет препятствовать тому, чтобы компилятор добавил '_'.

Или

3) прокомментируйте блок, скомпилируйте и посмотрите в файле списка (*.lst) для наблюдения то, чем становится имя маркировки.

1
ответ дан 5 December 2019 в 15:28
поделиться

Среда Turbo C++ имеет способ установить опции для TASM (я знаю, что часть Borland IDEs сделала)?

Если так, посмотрите, если изменение опции для "Максимальных передач (/m)" к 2 или больше помогает (это могло бы принять значение по умолчанию к 1 передаче).

Кроме того, при использовании длинного имени маркировки, которое могло бы создать проблему - по крайней мере один IDE имел набор по умолчанию к 12. Измените "Максимальную длину символа (/mv) опция".

Эта информация основана на Studio RAD Borland IDE:

1
ответ дан 5 December 2019 в 15:28
поделиться

Из того, что я вспоминаю, Вы не можете использовать внешнее (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;
}
0
ответ дан 5 December 2019 в 15:28
поделиться

Пара большего количества вещей (выстрелы в темноте) для попытки:

  • посмотрите, если использование следующей инструкции по сборке помогает:

    mov eax, offset SomeLabel
    
  • большинство компиляторов может произвести протокол ассемблирования кода, который они генерируют (не уверенный, если Turbo C++ может, так как Codegear/Embarcadero располагают его как бесплатный, непрофессиональный компилятор).

    Попытайтесь произвести список с кодом C, который имеет использование маркировка (как a goto будьте нацелены, например), с некоторым встроенным ассемблерным кодом в той же функции - но не пытайтесь получить доступ к маркировке от блока. Это так, можно получить компилятор без ошибок и протокол ассемблирования. Что-то как:

    int foo()
    {
        int x = 3;
        printf( "x =%d\n", x);
        goto SomeLabel;
                               //
        __asm {
            mov eax, 0x01
        }
                               //
    SomeLabel:
        printf( "x =%d\n", x);
                               //
        return x;
    }
    

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

1
ответ дан 5 December 2019 в 15:28
поделиться

Я думаю проблема, с которой Вы сталкиваетесь, то, что маркировка в __asm блок и маркировка в коде C++ являются двумя совершенно другими вещами. Я не ожидал бы, что Вы могли сослаться на маркировку C++ таким образом от встроенного ассемблерного кода, но я должен сказать, что это было очень долгое время, так как я использовал Turbo C++.

Вы попробовали lea инструкция вместо mov?

0
ответ дан 5 December 2019 в 15:28
поделиться

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

0
ответ дан 5 December 2019 в 15:28
поделиться

Просто предположение, так как я не использовал встроенный ассемблер ни с каким C / ++ компилятор...

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

Я не знаю точный синтаксис TASM.

0
ответ дан 5 December 2019 в 15:28
поделиться

Вот возможный метод:

// get_address
// gets the address of the instruction following the call
// to this function, for example
//     int addr = get_address (); // effectively returns the address of 'label'
//   label:
int get_address ()
{
    int address;
    asm
    {
        mov eax,[esp+8]
        mov address,eax
    }
    return address;
}
// get_label_address
// a bit like get_address but returns the address of the instruction pointed
// to by the jmp instruction after the call to this function, for example:
//     int addr;
//     asm
//     {
//       call get_label_address // gets the address of 'label'
//       jmp label
//       mov addr,eax
//     }
//     <some code>
//   label:
// note that the function should only be called from within an asm block.
int get_label_address()
{
    int address = 0;
    asm
    {
        mov esi,[esp+12]
        mov al,[esi]
        cmp al,0ebh
        jne not_short
        movsx eax,byte ptr [esi+1]
        lea eax,[eax+esi-1]
        mov address,eax
        add esi,2
        mov [esp+12],esi
        jmp done
    not_short:
        cmp al,0e9h
        jne not_long
        mov eax,dword ptr [esi+1]
        lea eax,[eax+esi+2]
        mov address,eax
        add esi,5
        mov [esp+12],esi
        jmp done
    not_long:
        // handle other jmp forms or generate an error
    done:
    }
    return address;
}
int main(int argc, char* argv[])
{
    int addr1,addr2;
    asm
    {
        call get_label_address
        jmp Label1
        mov addr1,eax
    }

    addr2 = get_address ();
Label1:
    return 0;
}

Это - немного hacky, но это работает в версии Turbo C++, который я имею. Это почти наверняка - иждивенец на настройках оптимизации и компиляторе.

0
ответ дан 5 December 2019 в 15:28
поделиться
Другие вопросы по тегам:

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