Risc processor the Negation of a register

897 views Asked by At

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

1

There are 1 answers

0
Seva Alekseyev On

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