Nano Hash - криптовалюты, майнинг, программирование

Синтаксис ASM at&t

поэтому у меня проблема с этим кодом. Это программа для преобразования двоичных чисел в десятичные.

#include <cstdlib>
#include <iostream>
#include <cstdio>

char s[100];
    int length;
    int a;


int main(int argc, char *argv[])
{

    system("cls");
    printf("\n\n  Vvedite stroky iz 0 i 1 (do 8 delementov) > ");
    gets(s);

    asm("leal s,%esi");
    asm("movl 8,%ecx");
    asm("movl 0,%edx");
    asm("repeat:");
    asm("movl 1,%eax");
    asm("dec %ecx");
    asm("rol %cl,%eax");
    asm("cmpb 31,%esi");
    asm("jnz x");
    asm("add %eax,%edx");
    asm("x: inc %esi");
    asm("cmpb 0,$esi");
    asm("jnz repeat");
    asm("movl %edx,a");

    printf("4islo %d",a);

    return EXIT_SUCCESS;
}

Выдает: "Ошибка сегментации (сброшено ядро)"

Пожалуйста, помогите с этой частью ASM. Думаю проблема в операторе CMPB.

08.01.2014

  • Я лично избегаю синтаксиса AT&T, но разве вы не должны ставить перед всеми непосредственными префиксами $ и все регистры с % ? (например, строка cmpb 0,$esi должна быть cmpb $0,%esi). 08.01.2014
  • Мне не кажется, что этот код действительно очень близок к выполнению этой работы. До тех пор, пока вы не привыкнете к написанию на ассемблере, часто бывает проще написать некоторый рабочий код на чем-то вроде c, затем написать код, который (примерно) делает то же самое на ассемблере. 08.01.2014
  • Каждый оператор asm независим. Вы не можете предполагать, что регистры содержат значения, которые вы принимаете, до или после каждого блока asm. Вы можете прочитать хорошее руководство по встроенной сборке GCC. 08.01.2014
  • @BrettHale У вас есть пример, когда это могло произойти? Из документов я понимаю, что текст каждого оператора asm копируется в сборку дословно, поэтому когда компилятор решит вставить дополнительные инструкции между двумя непосредственно следующими друг за другом операторами asm? 09.01.2014
  • @Andreas - нет выходов, входов или затертых операндов. С точки зрения компилятора они не имеют никакого эффекта. Лазейка здесь вот в чем: "An asm instruction without any output operands is treated identically to a volatile asm instruction.", которая гарантирует только то, что операторы asm не будут оптимизированы. Компилятор может вставлять инструкции между ними - происходит ли это на практике, не уточняется, и поэтому на него нельзя полагаться. (продолжение...) 09.01.2014
  • @Andreas ... Из того же раздела: "... you can't expect a sequence of volatile asm instructions to remain perfectly consecutive. If you want consecutive output, use a single asm. Also, GCC performs some optimizations across a volatile asm instruction ... " 09.01.2014
  • @BrettHale Спасибо - понял! 09.01.2014

Ответы:


1

Есть некоторые проблемы с этим кодом - в моей системе он даже не прошел через компилятор/ассемблер. Основная проблема заключается в том, что вам нужно ставить перед всеми литералами префикс $, иначе ассемблер предполагает доступ к памяти:

asm("movl 8,%ecx"); // tries to access memory at address 8 => Segmentation fault

Это должно быть

asm("movl $8,%ecx"); // Moves literal 8 into ecx

Соответственно отрегулируйте все остальные инструкции.

Другое дело следующая инструкция:

asm("cmpb 0,$esi");   // $esi is not a literal nor a register name

Это должно быть

asm("cmpb $0,(%esi)");  // compare value at address stored in %esi with literal 0 (end of string)

Я предлагаю вам скомпилировать код с отладочной информацией, например

$ g++ -g -o sample sample.c

Затем довольно легко отлаживать программу:

$ gdb sample 
(gdb) run
Starting program: sample 
sh: cls: command not found

   Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010

Program received signal SIGSEGV, Segmentation fault.
main (argc=1, argv=0x7fffffffe238) at sample.c:18
18          asm("movl 8,%ecx");   // current bit position

Как видите, отладчик показывает инструкцию, вызвавшую ошибку сегментации.

Обновить

Код сборки, который работал у меня, используя один оператор asm, предложенный @Brett:

asm("leal s, %esi         \n\t"   // s => %esi
    "movl $8, %ecx        \n\t"   // current bit position (+1)
    "movl $0, %edx        \n"     // initialize result

"repeat:                  \n\t"
    "movl $1, %eax        \n\t"   // Create bit mask in %eax
    "dec  %ecx            \n\t"   // Decrement rotation counter to shift mask bit to proper position
    "rol  %cl, %eax       \n\t"   // calculate value of current binary digit

    "cmpb $0x31, (%esi)   \n\t"   // current digit == 1?
    "jnz  x               \n\t"   // no, skip
    "add  %eax, %edx      \n"     // add current value to %edx

 "x:                      \n\t"
    "inc  %esi            \n\t"   // next address in input string
    "cmpb $0, (%esi)      \n\t"   // end of string reached?
    "jnz  repeat          \n\t"   // no, continue

    "movl %edx,a          \n");   // store result in a variable
$ ./sample 

  Vvedite stroky iz 0 i 1 (do 8 delementov) > 10101010
4islo 170
08.01.2014
  • Я изменил этот код, и он компилируется, но выдает ноль asm(leal s,%esi); asm(movl $8,%ecx); asm(movl $0,%edx); asm(повторить:); asm(movl $1,%eax); asm(dec%ecx); asm(рол %cl,%eax); asm(cmpl $31,%esi); asm(jnzx); asm(добавить %eax,%edx); asm(х:); asm(включая %esi); asm(cmpl $0,%esi); asm(jnz повтор); asm(movl%edx,a); printf(4islo%d\n,a); 08.01.2014
  • cmpl $31,%esi должно быть cmpb $31,(%esi) (косвенная адресация), и то же самое для cmpl $0,%esi должно быть cmpb $0,(%esi) 09.01.2014
  • Обратите внимание, что $31 также должно быть $0x31 (шестнадцатеричное значение 0x31 — это ASCII 1, а не десятичное значение 31) 09.01.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..