Сборка Как перевести код операции DIV в код C
Эй, я знаю, что задавал много вопросов... но не много ресурсов по этому вопросу в Google, так что, надеюсь, это поможет будущим людям, которые пытаются делать подобные проекты, я всегда тоже ищу решения Google, но я никогда не выполняю поиск на первой странице.
Я посмотрел на то руководство Intel, которое выложил Алекс, и кажется мне довольно чуждым http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-software-developer-vol-2a-2b-instruction-set-a-z-manual.html
Так что я думал, что знаю, как просто DIV
опкод сработал. Так как это просто divide
в конце концов. Я без труда добавил ADD
,SUB
, конечно IMUL
были проблемы, вы, ребята, помогли мне в этом. Кажется DIV
попадает в ту же категорию, что и IMUL
с точки зрения сложности.
Ну, не используя руководство, просто делайте тесты для самостоятельной отладки с OllyDbg.
Я узнал, что ответ деления всегда хранится в EAX
, Выяснил, остальное также хранится, кто знал, хранится в EDX
,
Который из изучения этого алгоритма чрезвычайно важен, кто знает, кто-то использовал бы остаток от деления случайных чисел, чтобы сгенерировать переход от 0-10 довольно умный. Но все же мой вопрос.
Это уже странно, я никогда не думал, что шестнадцатеричные числа деления будут иметь остатки, десятичные точки даже не принадлежат им.
DIV ECX
было бы как
regs.d.eax /= regs.d.ecx;
regs.d.edx = regs.d.eax % regs.d.ecx;
Я думал, может быть, сначала получить остаток... будут просто вещи.
regs.d.edx = regs.d.eax % regs.d.ecx;
regs.d.eax /= regs.d.ecx;
Хорошо, я едва работаю с математическим программированием, так что это немного сбивает с толку. Я скорее парень, который будет хранить результат в строке, а затем делить ее на десятичную точку, и вот как я получу остаток, да, я знаю, что он медленный, и он выбирает легкий путь... и я сам против использования строки операции в математическом коде.
Хорошо, хорошо.. глядя на тот код C я положил туда.. вероятно, придется хранить оба EAX
а также ECX
перед делением во временных переменных.. или сначала выполните код остатка.. затем код разделения. Я не знаю.
Ну, я посмотрю, может быть, вы, ребята, можете дать мне лучший ответ, возможно, это не может быть сделано в одной строке, но, возможно, я допустил несколько ошибок... Я не могу действительно проверить то, что я делаю сейчас, из-за многих других вещей, которые я нужно исправить, прежде чем я смогу скомпилировать программное обеспечение.
2 ответа
Руководства нелегко читать, правда, но в них есть все ответы на ваши вопросы (ну, большинство из них, есть случайные упущения и ошибки в документах).
Одна вещь, которую вы упускаете в своем предполагаемом алгоритме, состоит в том, что DIV обычно делит 2N бит на N бит, то есть когда вы делаете DIV ECX
64-разрядное значение без знака, содержащееся в EDX:EAX, делится на 32-разрядное значение без знака в ECX. Частное затем сохраняется в EAX, а остаток в EDX.
Также следует помнить о возможности переполнения деления (в этом случае EDX>=ECX является условием для этого) и флагов, которые инструкция изменяет в регистре EFLAGS.
Я думаю, что достаточно справедливый перевод будет:
int16_t a=42,b=7;
int16_t div = a/7;
int16_t remainder = a - (div*b);
На практике это может или не может быть эквивалентно remainder = a % b
(Мне нужно посмотреть стандартные характеристики). Будет интереснее, если внимательно рассмотреть, что происходит с отрицательными числами.
Все это говорит о том, что десятичная точка никогда не вступает в игру, поэтому я не понимаю, почему вы упоминаете об этом в посте.
возможно это не может быть сделано в одной строке [...]
Я очень подозреваю, что компилятор подхватит повторное использование подвыражений и автоматически использует остаток от (E)DX, когда это применимо. (это довольно тривиальная оптимизация для компилятора)