Как посчитать легкий пример?
Не получается посчитать пример Определить номер (n) элемента последовательности an = 3* n^2 – 5 * n + 12, при котором сумма элементов последовательности превысит 1500 По идее в конце N должна быть = 12. Код неправильно работает, я думаю из-за возведения в степень. Прошу помощи
int main() // начало программы на языке С++
{
long N = 0; // ячейка памяти для аргумента
long S = 0; // ячейка для хранения суммы
long P = 1; // ячейка для накопления 8n
long kv = 2;
long tri = 3;
_asm
{; начало ассемблерной вставки
m1 : inc N;// увеличение аргумента
//mov EBX, 3;// EBX = 3
mov EAX, P;// ECX = n(1)
mul kv;
mul tri;
mov P, EAX; // 3*n^2 in P
add S, EAX;// накопление суммы
mov EAX, 5;// EAX = 5
mul N;// EAX = 5 * n
sub S, EAX;// накопление суммы
mov EAX, N;// EAX = n
add EAX, 12;
add S, EAX;
cmp S, 1500;// сравнение суммы с 1500
jc m1;// переход, если сумма меньше 1500
}
}
Ответы (2 шт):
Автор решения: Zhihar
→ Ссылка
int res = 0;
__asm {
mov ecx, 0 ; счётчик n
mov edx, 0 ; счётчик суммы
calc_loop:
mov eax, ecx ; вычисляем 5n
mov esi, 5
mul esi
mov ebx, eax
mov eax, ecx ; вычисляем 3n^2
mul ecx
mov esi, 3
mul esi
sub eax, ebx ; вычисляем 3n^2 - 5n + 12
add eax, 12
add edx, eax ; увеличиваем сумму
inc ecx ; увеличиваем n
cmp edx, 1200 ; если сумма менее 1200 выполняем этап вычислений еще раз
jl calc_loop
mov res, ecx
}
std::cout << res << std::endl;
так?
Автор решения: vp_arth
→ Ссылка
Член последовательности, для простоты, можно представить как (3n-5)*n + 12
Решение для суммы ряда:
asm (
"xor ebx, ebx;" // sum = 0;
"xor ecx, ecx;" // n = 0;
"it:" // do {
"lea eax, [ecx+ecx*2];" // an = (3*n
"sub eax, 5;" // - 5)
"mul ecx;" // * n
"add eax, 12;" // + 12;
"add ebx, eax;" // sum += an;
"cmp ebx, 1500;" // if (sum > 1500)
"jg res;" // break;
"inc ecx;" // ++n;
"jmp it;" // } while (true);
"res:mov %0, ecx;"
: "=r" (dst) // 12
);
Решение от компилятора.
Ниже решение не той задачи. Ищет член превышающий 1500 :(
// g++ -masm=intel tmp.cpp -o /tmp/tmp && /tmp/tmp
#include <cstdio>
int main()
{
int dst;
// an = 3* n^2 – 5 * n + 12, an > 1500
// (3n-5)*n + 12
asm (
"xor ecx, ecx;"
"it:" // do {
"lea eax, [ecx+ecx*2];" // an =(3*n
"sub eax, 5;" // -5)
"mul ecx;" // *n
"add eax, 12;" // +12;
"cmp eax, 1500;" // if (an > 1500)
"jg res;" // break;
"inc ecx;" // ++n;
"jmp it;" // } while (True);
"res: mov %0, ecx;"
: "=r" (dst)
);
printf("%d\n", dst); // 24
}
Посмотрел, что GCC генерирует на код выше в комментариях, что-то вроде:
asm (
"mov DWORD PTR [rbp-8], 0;"
"mov DWORD PTR [rbp-4], 0;"
".L_1: mov edx, DWORD PTR [rbp-4];"
"mov eax, edx;"
"add eax, eax;"
"add eax, edx;"
"sub eax, 5;"
"imul eax, DWORD PTR [rbp-4];"
"add eax, 12;"
"mov DWORD PTR [rbp-8], eax;"
"cmp DWORD PTR [rbp-8], 1500;"
"jg .L_2;"
"add DWORD PTR [rbp-4], 1;"
"jmp .L_1;"
".L_2: mov %0, DWORD PTR [rbp-4];"
: "=r" (dst)
);
я на 3 умножаю интереснее))