Witam.
Czy mógłby mi ktoś wytłumaczyć jak dokładnie działa polecenie DADD w assemblerze?
Czytałem o nim w książce i kilku źródłach, ale wciąż nie do końca je rozumiem, np. co się dzieje z flagą C, gdy zakres zostanie przekroczony?
Proszę o pomoc.
MSP430? Co prawda dokumentacji nie mam pod ręką, ale raczej C jest ustawiane iff rezultat przekroczy 9999 (dla operacji 16-bit, 99 dla 8-bit).
Tak. Ale jak np. mam w R5 liczbe 5 a w R6 liczbe 6 to co się pojawi w poszczególnych rejestrach. Jak ta flaga C jest przenoszona bo w internecie znalazłem tylko, że dst+= dst+src+C BCD.
Coś o tym że wynik jest podwajany itp.
Imo R5=0x11, C=0. O podwajaniu nic nie słyszałem - ewentualnie może chodziło o to, że jeśli użyjemy tego samego rejestru jako src i dst, to będzie to równoznaczne np. R5 += R5, czyli podwojeniu R5.
No dobra ale czy DADD to nie liczby dziesiętne od 0 do 9? Czy ten zakres nie zostanie przekroczony? I jak flaga zostaje przeniesiona po przekroczeniu?
Tu przykładowy kod z książki:
move.w r12,r14
clr.w r12
clr.w r13
mov.w #0x0010, r15
Loop:
rla.w
dadd.w r12, r12
dadd.w r13,r13
dec.w r15
jnz Loop
reta
; ret
END
Tutaj opis jaki znalazłem:
The eight-digit BCD number contained in R5 adn R6 is added decimaly to an eight-digid BCD number contained in R3 and R4 (R6 and R4 contain the MSDs)
Niżej kod do tego:
CLRC ;clear carry
DADD r5,r3 ;add LSDs
DADD r6,r4 ;add MSDs with carry
JC OVERFLOW ; if carry occurs go to error handling routine
Polecam poczytać o BCD (np. https://pl.wikipedia.org/wiki/Kod_BCD).
No dobra ale czy DADD to nie liczby dziesiętne od 0 do 9?
Po pierwsze, precyzyjniej mówiąc DADD to instrukcja, a nie liczby. Po drugie, już pisałem wyżej - DADD traktuje rejestry jako czterocyfrowe dziesiętne liczby zapisane w kodzie BCD. Przykładowo jeśli na początku R4 = 0x6789, R5 = 0x2345, to po wykonaniu DADD R5, R4 otrzymamy R4 = 0x9134, bo dziesiętnie 6789 + 2345 = 9134.
I jak flaga zostaje przeniesiona po przekroczeniu?
Jeśli przekroczymy 9999, to C jest ustawione, w przeciwnym razie wyzerowane.
Jeśli chodzi o ten kod wyżej, to byłoby lepiej jakbyś przepisał go bez błędów (jak brak argumentu do rla.w) i z komentarzami z książki (wątpię żeby po prostu wstawili taki fragment kodu bez wyjaśnień, bo mijałoby się to z celem). Na pierwszy rzut oka wydaje się to być funkcją do zamiany liczby zapisanej normalnie na taką w kodzie BCD, poprzez dodawanie dziesiętnie bit po bicie liczby wejściowej, a następnie mnożenie przez dwa wyniku (bo src = dst w operacjach DADD z przykładu).
Poprawiony kod:
move.w r12,r14 ; move input and leave r12 free for result
clr.w r12 ; clear registers for result
clr.w r13
mov.w #0x0010, r15 ; initialize loop counter to number of bits
Loop:
rla.w r14 ;shift msb of input into carry bit
dadd.w r12, r12 ;r13:r12 = 2*r13:r12 + carry bit DECIMALY
dadd.w r13,r13 ; lsword then msword
dec.w r15 ; decrement loop counter
jnz Loop ; repeat if nonzero
reta ;return instruction in MSP430X
; ret ; Usual MSP430 return instruction
END