Кто тут в ассемблере шарит? (fasm) Есть лаба - возвести число X в 32 степень. Из команд можно использовать только умножение не более пяти раз. Окей, пять раз перемножить число само на себя много ума не надо, и как раз получается 32 степень, но что делать с ебучим переполнением? Можно как-то использовать несколько регистров в качестве одной переменной? Если использовать тупой подход, то нужна переменная размером 8 байт хотя бы, но таких, вроде бы, нет. Может какие-то хитрые алгоритмы есть?
Короче, спасайте, это пиздец какой-то. У всех остальных задачки вроде «посчитать число сотен в числе» или «найти объем куба со стороной X», а мне такой вот хардкор достался.
Блять, двач, я должен решить эту херню на чистом ассемблере, встроенном в C++, хотя бы ради того, чтобы не чувствовать себя говном.
В общем, решаем всем двачом двумя вариантами: 1. Законно: с использованием только умножения не более пяти раз, можно изменять и баловаться только с регистрами. 2. На похуях: любые варианты, лишь бы работало.
>>258915643 Нихуя не понимаю, что там и как это использовать. Я, блять, с ассемблером первый раз в жизни встретился.
>>258915491 И как его там смотреть-то, блять? Вывожу по-отдельности eax, ebx, edx и там числа что-то вроде 24473687, 0 и 9, а что это значит, я не представляю.
>>258916153 Ну блин, я не буду ради тебя масм ставить. Что-то вроде mov ax, [num1] mov bx, [num2] mul bx mov [mulResult],ax mov [mulResult+2],dx mov eax,[mulResult]
>>258917293 Использовать несколько регистров для одного числа. В инете можно найти примеры умножения огромных чисел, там так и организовано. Также использовать флаг переполнения в качестве детектора.
>>258914883 (OP) Бля, я учился лет 15 назад, ассемблер решал всей параллели, щас конечно уже не вспомню. Эхх надо было пограмистом идти, а щас уж все мозги пропил.
>>258917543 >>258917344 Ну, вот, блять, юзаю сдвиги. Сдвиг на 10 бит - окей, ибо нет переполнения. Сдвиг на 15 бит - окей, ибо опять нет переполнения. Сдвиг на 31 бит - всё, пиздец, переполнили 4 ебучих байта.
>>258918146 Было бы заебись, если бы можно было бы два 4-байтовых регистра в один 8-байтовых, но нельзя, потому что архитектура x32, а не x64, если я правильно понимаю.
Я думаю, что правильное решение то, которое ты нашёл, а препод про ошибку просто не подумал. Тем более у других такие лёгкие задачи. Такие неудачные задания у меня были в учёбе,препод потом признавал, что сделано все правильно, хотя результата нет.
>>258914883 (OP) Берёшь и спрашиваешь препода, надо ли учитывать переполнение. Решаешь только если сказал да и нет возможносьи взять другое задание/препода.
Ну, смотри. Соль тут уже просто в том, чтобы найти способ, решить это говно. До появления 64-битной архитектуры каким-то же образом должны были считать большие числа ассемблером.
>>258918378 Умножение на себя удваивает число разрядов. Так что опу понадобится 32 байта если исходное число один байт. А если там инт32, то 4х32 = 128 байт.
Так что опу нужна плавающая запятая. Там можно читать и писать через поинтер 32, 64 и 80 бит.
>>258919081 > сложение в цикле Всё равно переполнение никуда не уйдет Может возможно как-нибудь части числа раскидать по разным регистрам, но как потом собрать их в кучу и вывести результат?
>>258919385 Ну так разбей результат и запиши в верхнем и нижнем регистрах. Асс-эмблер позволяет работать с любыми числами, на сколько хватит ячеек памяти.
>>258919482 >Ну так разбей результат и запиши в верхнем и нижнем регистрах Каким образом? Каким образом потом продолжать двигать регистры? Каким образом вывести результат во внешнюю переменную?
>>258919649 Алгоритм я тебе скинул на Википедии. Сдвиги не нужны, не слушай даунов. Тебе придется для честного решения ворочать массивы на ассемблере и объявлять подпрограммы.
И определись, ты на fasm или на вставках ищешь решение? Фасм это отдельный от си проект.
>>258919920 Да, спасибо за статью и за исправление. Нужно всё сделать на вставках си.
Думаю, придётся ворочать массивы и объявлять подпрограммы. Больше всего меня напрягает вывод данных. Я не представляю как собрать данные разных регистров во внешней 64-битной переменной. Скорее всего придётся писать новый класс, а это снова отход от принципа, что на языке должен выполняться только ввод и вывод данных, а вся логика внутри ассемблера.
Если выберешь большие числа, то есть два варианта: использовать обычный массив unsigned int и потом ебаться с делением, чтобы вывести на экран результат. Или использовать массив BCD (https://ru.m.wikipedia.org/wiki/Двоично-десятичный_код)
>>258920115 Размер переменных хотелось бы, конечно 8 байт, но вставки в C++ поддерживают только 4 байта, так что буду брать их. Скорее всего буду работать с длинной математикой.
>>258920383 Тогда начни с того, что объяви массив unsigned int и передай его по ссылке в ассемблер и попробуй что-нибудь с ним сделать, увеличить на единицу все элементы, например. Это нужно чтобы понять формат хранения массива, который сделает компилятор.
>>258920383 Для 4 байт на входе будет 128 байт на выходе. В любом случае передавать нужно будет ссылку на число, а не само число. Так что не важно, что он там поддерживает.
Вроде нет алгоритма, который позволил бы по частям посчитать степень, так что юзать только регистры вообще не вариант. Создавай массив на 128 байт, если ввод на 4 байта, запиши туда X и возведи в квадрат 5 раз, как ты и предлагал. Единственная проблема на твоём пути это тупо функция возведения в квадрат, которая как аргумент должна брать не регистр, а указатель на массив байт, которые ты и будешь возводить.