Dodawanie 5 liczb

0

Witam, jestem początkującym programistą, więc proszę o wyrozumiałość.

Zaczałęm programowanie w Assemblerze. Chcę napisać skrypt w Assemblerze z wykorzystaniem języka C (w sensie dwa oddzielne pliki) realizujące sumowanie 5 liczb. O ile z dodawaniem 4 nie ma problemu, bo wykorzystać można do tego 4 rejestry, o tyle z 5 składnikiem trzeba zastosować stos. I tu jest mój problem: nie wiem jak się do tego stosu zabrać. Mam zrobione skrypty dodające 4 liczby i chcę rozszerzyć je możliwość dodawanie piątej. Jakieś porady?

0

Dodasz co do tej pory napisałeś?

EDIT
Cieżko coś zrobić jak nie dałeś kodu.

Z Twojego postu wnioskuję, że masz funkcję mniej więcej taką:

 int dodaj(int a, int b, int c, int d, int e);

Nie podałeś też rodziny procesorów, więc zakładam, że x86.

bo wykorzystać można do tego 4 rejestry
Jest więcej rejestrów niż 4. http://pl.wikibooks.org/wiki/[...]y_og.C3.B3lnego_przeznaczenia

Ale jeżeli potrzebujesz 5 rejestrów do dodania 5 liczb to zakładam, że robisz coś takiego

mov eax, liczba1
mov ebx, liczba2
... 

co nie jest dobrym pomysłem.

Dam dwa przykłady.

Dla funkcji

 int dodaj(int a, int b, int c, int d, int e);
 .686
.model flat
public _dodaj
.code
_dodaj PROC
    push ebp ; zapisanie zawartosci EBP na stosie
    mov ebp,esp ; kopiowanie zawartosci ESP do EBP
    push ebx ; przechowanie zawartosci rejestru EBX
    push ecx

    mov eax, 0

    mov ebx, ebp
    add ebx, 8 ; teraz w ebx jest wskaznik na pierwsza liczbe

    mov ecx, 5 ; ile bedzie liczb

dodawanie:
    add eax, [ebx]
    add ebx, 4
    loop dodawanie

    pop ecx
    pop ebx
    pop ebp
    ret
 _dodaj ENDP
END 

dla funkcji

 int dodaj(int tab[], int rozmiar);
 .686
.model flat
public _dodaj
.code
_dodaj PROC
    push ebp ; zapisanie zawartosci EBP na stosie
    mov ebp,esp ; kopiowanie zawartosci ESP do EBP
    push ebx ; przechowanie zawartosci rejestru EBX
    push ecx

    mov eax, 0 ; zerujemy wynik
    mov ecx, [ebp+12] ; do eax dajemy rozmiar
    mov ebx, [ebp+8] ; pobranie wskaznika na tablice

dodawanie:
    add eax, [ebx] ; dodajemy kolejna liczbe
    add ebx, 4 ; przechodzimy do nastepnej liczby
    loop dodawanie

    pop ecx
    pop ebx
    pop ebp
    ret
 _dodaj ENDP
END

Ten sposób jest chyba lepszy bo nie ogranicza nas co do ilości liczb (w sumie ogranicza przez maksymalną wielkość inta).

0

Przepraszam za niedopisanie. Chodzi i procesory 64-bitowe, a dodawanie liczb odbywa się poprzez dodanie 5 intów, a nie tablicy.

0

Poczytaj o opcji -S kompilatora gcc.

0
gronholm napisał(a):

trzeba zastosować stos. I tu jest mój problem: nie wiem jak się do tego stosu zabrać.

Rozwiązanie w asemblerze MASM64 z użyciem stosu.

includelib D:\Lib\AMD64\Kernel32.Lib
extrn  ExitProcess: PROC 

.data

.code
Main proc
    push 2 ; pierwsza liczba
    push 2 ; druga liczba
    push 2 ; trzecia liczba
    push 2 ; czwarta liczba
    push 2 ; piąta liczba
    xor rax, rax
    xor rcx, rcx
sum:
    cmp rcx, 5
    je exit
    pop rdx
    add rax, rdx
    inc rcx
    jmp sum
exit:
    xor rcx, rcx
    call ExitProcess
Main endp

end

Budowanie:

cd "C:\Program Files\Microsoft Platform SDK\Bin\win64\x86\AMD64"
ml64 /c sum.asm 
link /subsystem:windows /entry:Main sum.obj
pause
0

Liczby, które mam zsumować, mają się znajdować w pliku *.c. Coś na wzór skryptu z pierwszej odpowiedzi, tylko w wersji x64

0

W takim razie chodzi Ci chyba o użycie Inline Assembly?

Kod dla kompilatora gcc:

#include <stdio.h>

int sum(int p1, int p2, int p3, int p4, int p5)
{
    asm ("add %1, %0" : "+a" (p1) : "r" (p2) : "cc");
    asm ("add %1, %0" : "+a" (p1) : "r" (p3) : "cc");
    asm ("add %1, %0" : "+a" (p1) : "r" (p4) : "cc");
    asm ("add %1, %0" : "+a" (p1) : "r" (p5) : "cc");

    return p1;
}

int main(void)
{
    printf("1+2+3+4+5 = %d", sum(1,2,3,4,5)); // 1+2+3+4+5 = 15

    return 0;
}
0

Przecież już dostałeś odpowiedź gdzie wziąć poprawny kod assemblera dowolnej funkcji pod dowolny system na dowolnej platformie: opcja kompilatora -S

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0