#define Z IP
#define I FP
#define J LR
#define INPUT_VALUE 30
; in C
; int factorial(int n) {
; if (n <= 1) {
; return 1;
; } else {
; return n * factorial(n-1);
; }
;}
; in DCPU
:factorial
@ Store link register on stack
SUB SP, 2
SET [SP], LR
@ Store frame pointer on stack
SUB SP, 2
SET [SP], FP
@ Set frame pointer to start of frame
SET FP, SP
@ Allocate n on the stack
SUB SP, 2
SET [SP], A
@ Load n
SET C, FP
SUB C, 2
SET C, [C]
@ compare n and 1
IFG C, 1
@ Handle the else branch
SET PC, factorial_recurse
@ Handle the if branch
@ Return 1
SET A, 1
SET PC, factorial_end
:factorial_recurse
@ Call factorial with n-1
SET A, FP
SUB A, 2
SET A, [A]
SUB A, 1
MOV PC, factorial
@ Multiply returned value by n and return
SET C, FP
SUB C, 2
SET C, [C]
MUL A, C
SET PC, factorial_end
:factorial_end
@ Unwind stack and return
SET SP, FP
SET FP, [SP]
ADD SP, 2
SET LR, [SP]
SET PC, LR
:main
@ Push LR to stack
SUB SP, 2
SET [SP], LR
@ Call factorial with parameter INPUT_VALUE
SET A, INPUT_VALUE
SET PC, factorial
@ Return the value returned by factorial
ADD SP, 2
SET PC, LR
I2RlZmluZSBaIElQCiNkZWZpbmUgSSBGUAojZGVmaW5lIEogTFIKCiNkZWZpbmUgSU5QVVRfVkFMVUUgMzAKCjsgaW4gQwo7IGludCBmYWN0b3JpYWwoaW50IG4pIHsKOyAJaWYgKG4gPD0gMSkgewo7CQlyZXR1cm4gMTsKOwl9IGVsc2Ugewo7CQlyZXR1cm4gbiAqIGZhY3RvcmlhbChuLTEpOwo7CX0KO30KCjsgaW4gRENQVQo6ZmFjdG9yaWFsCglAIFN0b3JlIGxpbmsgcmVnaXN0ZXIgb24gc3RhY2sKCVNVQiBTUCwgMgoJU0VUIFtTUF0sIExSCgkKCUAgU3RvcmUgZnJhbWUgcG9pbnRlciBvbiBzdGFjawoJU1VCIFNQLCAyCglTRVQgW1NQXSwgRlAKCglAIFNldCBmcmFtZSBwb2ludGVyIHRvIHN0YXJ0IG9mIGZyYW1lCglTRVQgRlAsIFNQCgoJQCBBbGxvY2F0ZSBuIG9uIHRoZSBzdGFjawoJU1VCIFNQLCAyCglTRVQgW1NQXSwgQQoKCUAgTG9hZCBuCQoJU0VUIEMsIEZQCglTVUIgQywgMgoJU0VUIEMsIFtDXQoKCUAgY29tcGFyZSBuIGFuZCAxCglJRkcgQywgMQoKCUAgSGFuZGxlIHRoZSBlbHNlIGJyYW5jaAoJU0VUIFBDLCBmYWN0b3JpYWxfcmVjdXJzZQoKCUAgSGFuZGxlIHRoZSBpZiBicmFuY2gKCUAgUmV0dXJuIDEKCVNFVCBBLCAxCglTRVQgUEMsIGZhY3RvcmlhbF9lbmQKCQo6ZmFjdG9yaWFsX3JlY3Vyc2UKCUAgQ2FsbCBmYWN0b3JpYWwgd2l0aCBuLTEKCVNFVCBBLCBGUAoJU1VCIEEsIDIKCVNFVCBBLCBbQV0KCVNVQiBBLCAxCglNT1YgUEMsIGZhY3RvcmlhbAoJQCBNdWx0aXBseSByZXR1cm5lZCB2YWx1ZSBieSBuIGFuZCByZXR1cm4KCVNFVCBDLCBGUAoJU1VCIEMsIDIKCVNFVCBDLCBbQ10KCU1VTCBBLCBDCglTRVQgUEMsIGZhY3RvcmlhbF9lbmQKCQo6ZmFjdG9yaWFsX2VuZAoJQCBVbndpbmQgc3RhY2sgYW5kIHJldHVybgoJU0VUIFNQLCBGUAoJU0VUIEZQLCBbU1BdCglBREQgU1AsIDIKCVNFVCBMUiwgW1NQXQoJU0VUIFBDLCBMUgoJCjptYWluCglAIFB1c2ggTFIgdG8gc3RhY2sKCVNVQiBTUCwgMgoJU0VUIFtTUF0sIExSCgoJQCBDYWxsIGZhY3RvcmlhbCB3aXRoIHBhcmFtZXRlciBJTlBVVF9WQUxVRQoJU0VUIEEsIElOUFVUX1ZBTFVFCglTRVQgUEMsIGZhY3RvcmlhbAoKCUAgUmV0dXJuIHRoZSB2YWx1ZSByZXR1cm5lZCBieSBmYWN0b3JpYWwKCUFERCBTUCwgMgoJU0VUIFBDLCBMUg==