Question

My output is supposed to look like this according to the spec:

00:00
00:01
00:12
01:23
12:34
23:45
34:56
45:67
56:78
67:89
78:9A
89:AB
9A:BC
AB:CD
BC:DE
CD:EF
DE:F0
EF:01
F0:12
01:23
12:34

and so on. I've written 2 assembly subroutines, one which does the hexadecimal conversion and one that gets the digit to print from the test program and I'm now getting this output which is starting to resemble what it should look like:

0:
1:
2:
3:
4:
5:
6:
7:
8:
9:
A:
B:
C:
D:
E:
F:
0:
1:
2:
3:
4:
5:

So it appears that I'm getting the rightmost digit right but how should I get the rest of the digits? It says in the assignment that

Example: Memory location 0x0047114 contains the binary value 0101 0011 (hexadecimal 0x53) Memory location 0x0047115 contains the binary value 0001 0110 (hexadecimal 0x16) Memory location 0x0047116 contains the binary value 0000 0000 (hexadecimal 0x00) Memory location 0x0047117 contains the binary value 0000 0000 (hexadecimal 0x00) The caller sets register r4 to 0x0047114 and calls puttime; puttime prints out 16:53 on a new line.

More background is available from other questions I recently posted that are same assignment but focusing on other parts of it:

https://stackoverflow.com/questions/12105322/how-to-proceed-coding-for-this-assignment

Difference between load word and move?

https://stackoverflow.com/questions/12152323/why-is-load-word-not-working

My program that makes the conversion is:

.global hexasc 

        .text
        .align 2

hexasc: movi r8, 0x09
        movi r9, 0x0f
        andi r4, r4, 0x0f #keep only 4 bits
        bgt r4, r8, L1  #is x>9?
        movi r2, 0x30
        add r2, r2, r4  
        andi r2, r2, 0xff
        ret  

L1:     movi r2, 0x37
        add r2, r2, r4
        andi r2, r2, 0xff
        ret

I think the above is correct and working, but I'm not sure how to program the middle part which gets the variable and passes it on to my subroutine:

.macro PUSH reg
        subi    sp, sp, 4
        stw     \reg, 0(sp)
.endm

.macro POP reg
        ldw     \reg, 0(sp)
        addi    sp, sp, 4
.endm

.global puttime 

        .text
        .align 2

puttime: 
        PUSH r31
        ldw r8,0(r4)            # put the variable in register 8
        PUSH r8
        nop
        movi r4, 0x0A           # put newline char in register 4
        movia   r9,putchar      # copy subroutine address to a register
        callr   r9              # call subroutine via register
        POP r8
        mov r4, r8
        call hexasc
        mov r4, r2
        movia   r9,putchar      # copy subroutine address to a register
        callr   r9
        movi r4, 0x3A
        movia r9, putchar
        callr r9
        POP r31
        ret

Any help is greatly appreciated.

Was it helpful?

Solution

I think you need to call hexasc twice, once for each hex digit in your input data. You will need to shift the input data right 4 bits between each call of hexasc, because hexasc only converts the bottom 4 bits of the input data.

By the way, using PUSH and POP is not idiomatic MIPS code. In MIPS you typically subtract a constant value from the stack pointer on entry to a routine and add the constant value back on exiting from the routing. Like this:

puttime:
  subi sp, 8       # reserve space for 2 words on the stack
  sw   r31, 4(sp)
  ...
  lw   r31, 4(sp)
  addi sp, 8
  ret
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top