Good afternoon! Here is my task:

Four natural numbers are given. Implement the subroutine to find their smallest common multiple. (realize as assembly insertion C ++)

#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 } } 

How to remake a given tasm-insert for an assembler insert in C ++ without .data and .model small? Searched the Internet - found nothing about it.

    1 answer 1

    First, there is a 16-bit assembler for MS-DOS, which needs to be redone to 32-bit. To do this, before the names of all registers you need to add E (push bp -> push ebp). Secondly, there in code 2 functions for LCM and GCD, I decided to ctrl + c, ctrl + v them into separate naked functions, in which the compiler does not add any ad-libbing. In gcd, for some reason, 12 bytes are reserved for local variables that are not there, I just removed this line. x equ word ptr [bp + 6] y equ word ptr [bp + 4] should also be removed. I also had to rename some labels so that the compiler would not swear. It turned out like this:

     #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; }