День добрый! Вот моя задача:
Задано четыре натуральных числа. Реализуйте подпрограмму нахождения их наименьшего общего кратного. (реализовать как ассемблерную вставку С++)
#include <iostream>
using namespace std;
int nod(int a, int b) {
int rez;
a = a > 0 ? a : -a;
b = b > 0 ? b : -b;
if (a == 0)
rez = b;
else if (b == 0)
rez = a;
else if (a == b)
rez = a;
else if (a == 1 || b == 1)
rez = 1;
else {
int ra = a % 2, rb = b % 2;
if (!(ra || rb))
rez = 2 * nod(a / 2, b / 2);
else if (!ra)
rez = nod(a / 2, b);
else if (!rb)
rez = nod(b / 2, a);
else if (a > b)
rez = nod(a - b, b);
else
rez = nod(b - a, a);
}
return rez;
}
int nok(int a, int b) {
return a * b / nod(a, b);
}
int main() {
int a, b, c, d;
cout << "A, B, C, D\n";
cin >> a >> b >> c >> d;
cout << "NOK(A, B, C, D) = " << nok(nok(nok(a, b), c), d) << endl;
_asm {
.model small //tasm часть
.data
a dw 8
b dw 12
.code
start :
mov ax, @data
mov ds, ax
push a
push b
call lcm; //результат в ax
xor ax, ax
int 16h
.exit
x equ word ptr[bp + 6]
y equ word ptr[bp + 4]
gcd:
push bp
mov bp, sp
sub sp, 12
mov ax, x
cmp ax, y
jge @1
mov ax, x
mov bx, y
mov x, bx
mov y, ax
@1:
mov ax, x
cwd
mov bx, y
idiv bx
test dx, dx
jne @2
mov ax, y
jmp @exit_gcd
@2:
push dx
mov ax, y
push ax
call gcd
@exit_gcd:
mov sp, bp
pop bp
ret
lcm :
push bp
mov bp, sp
push x
push y
call gcd
mov bx, ax
mov ax, x
imul y
cwd
idiv bx
mov sp, bp
pop bp
ret
end start
}
}
Как переделать данную tasm-вставку под вставку ассемблера на C++ без .data и .model small? Проискал просторы Интернета - ничего по этому поводу не нашел.
Во-первых, тут 16 битный ассемблер для MS-DOS, который надо переделать в 32 битный. Для этого перед именами всех регистров нужно добавить E (push bp -> push ebp). Во-вторых, там в коде 2 функции для НОК и НОД, я решил ctrl+c, ctrl+v их в отдельные naked функции, в которые компилятор не добаляет никакой отсебятины. В gcd зачем-то резервируются 12 байт для локальных переменных, которых нет, я просто убрал эту строку. x equ word ptr[bp + 6] y equ word ptr[bp + 4] нужно тоже убрать. Еще пришлось переименовать некоторые метки, чтобы компиляотр не ругался. Получилось так:
#include <iostream>
using namespace std;
int __declspec(naked) gcd(int x, int y)
{
__asm {
push ebp
mov ebp, esp
mov eax, x
cmp eax, y
jge l1
mov eax, x
mov ebx, y
mov x, ebx
mov y, eax
l1 :
mov eax, x
cwd
mov ebx, y
idiv ebx
test edx, edx
jne l2
mov eax, y
jmp exit_gcd
l2 :
push edx
mov eax, y
push eax
call gcd
exit_gcd :
mov esp, ebp
pop ebp
ret
}
}
int __declspec(naked) lcm(int x, int y)
{
__asm {
push ebp
mov ebp, esp
push x
push y
call gcd
mov ebx, eax
mov eax, x
imul y
cwd
idiv ebx
mov esp, ebp
pop ebp
ret
}
}
int main() {
int a, b, c, d;
cout << "A, B, C, D\n";
cin >> a >> b >> c >> d;
cout << "NOK(A, B, C, D) = " << lcm(lcm(lcm(a, b), c), d) << endl;
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
У меня запускается код с компилятором gnu++1y, но при использовании gnu c++ 11 49 выдает ошибку
Хочу организовать проверку форматирования кода на стороне ci с помощью clang-format и опции -output-replacements-xmlЗадумка была такая: если файл не отформатирован,...
Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы он соответствовал тематике «Stack Overflow на русском»
Хочу расширить свои навыки как программиста в направлении кроссплатформенностиХочу изучить создание приложений на линуксе, использование...