Reputation: 95
We consider a RISC processor that have only a few command like DBNZ. I am trying to write code that writes the negation of a Register A into B and also second separate code that it should subtract A from B and put the result into C
I am not sure how to do it I don't really maybe it could be possbile with Nasm Assembler but those are two different things but not sure how to start
Upvotes: -2
Views: 978
Reputation: 61331
For the record, real RISC architectures (e. g. ARM or MIPS) are richer than DBNZ. What you envision is usually designated as an OISC or a URISC.
NASM, by the way, would be of no help. It only targets real life CPUs; yours is an academic model. But putting together an emulator in a high level language would be rather trivial. I can probably write one in JavaScript in an hour or so.
The syntax I'm assuming for its only command is:
DBNZ reg[, label]
and the meaning is:
reg = reg - 1
if label is given and reg != 0 then goto label
If label is omitted, the implicit jump target is just the next instruction. It's a lump of syntactic sugar for me, for better code readability.
Everything after semicolon to the end of the line is a comment. Labels are terminated with colon. My code assumes that registers have finite size, and integer wrap-around happens quietly, without exceptions.
The algorithm for negation is easy enough:
b=0
while a > 0
a = a-1
b = b-1
In assembly, the conditional jump and the decrement are one and the same. So it would go like this:
;Zero out B
BZeroLoop:
DBNZ B, BZeroLoop ; Decrement until it's zero
;Main loop: subtract from A until it's zero, decrementing B on every iteration
NegLoop:
DBNZ B ; Decrement B with no jump
DBNZ A, NegLoop
Now the subtraction. The algorithm for subtracting B from A in place (i. e. result stays in the A register) goes:
while b != 0
b = b-1
a = a-1
It's in fact the same loop as in negation, but without the initial zeroing out. You can think of negation as of a case of subtraction in place - specifically, it's subtracting from zero.
But we need the result to go into c. In a less stunted language, we'd just assign. But we don't have assignment. It's possible to do assignment with two negations and a temp register. But we can make do with one negation - first, calculate b-a in place, then negate it to c:
while a != 0
a = a-1
b = b-1 ;this reduces b to the value of b-a
c = 0 ; also a loop
while b != 0
b = b-1
c = c-1
Or, in assembly:
SubLoop: ; B = B-A
DBNZ B
DBNZ A, SubLoop
CZeroLoop: ; C = 0
DBNZ C, CZeroLoop
NegLoop: ; C = C-B
DBNZ C
DBNZ B, NegLoop
Upvotes: 3