Im trying to copy the LR to R0 to return the calling function’s address to some other function, but Im coming with some issues. Im modifying my division libraries to detect a divide by zero and return the calling function’s address back to another function to record the initial division’s address
I have two similar assembly functions, one 32 bit which works fine, and a 16 bit which does not. The 32 bit div function looks something like this:
============
.state32
.global U_DIV
.global U_MOD
.global _div_zero
dvs .set r2 ; WORK COPY OF THE DIVISOR (SHIFTED)
quo .set lr ; WORK COPY OF THE QUOTIENT
osp .set r3
U_DIV:
U_MOD:
STMFD sp!, {dvs, lr} ; SAVE CONTEXT
MOVS dvs, r1 ; CHECK FOR DIVISION BY ZERO
BEQ div_by_zero
<rest of code>
div_by_zero:
MOV a1, LR ; Copy LR to A1 to return to div_zero
BL _div_zero ; Call to div_zero
MOV r0, #0 ;
LDMFD sp!, {dvs, pc} ;
.end
============
This works fine. My div_zero function gets the address stored in the LR and I can do what I want with it. I try to do something similar with the 16 bit and the same code crashes. Unfortunately, I dont have an emulator, so Im trying this blind
The 16 bit code looks something like this
============
.state16
.align ; REQUIRED SO ADD PC IS WORD ALIGNED BELOW
.global U$DIV
.global U$MOD
.global _div_zero
dvs .set r2 ; WORK COPY OF THE DIVISOR (SHIFTED)
quo .set r3 ; WORK COPY OF THE QUOTIENT
tmp .set r4
U$DIV:
U$MOD: PUSH {r2-r4} ; SAVE CONTEXT
MOV dvs, r1 ; INITIALIZE THE DIVISOR (SHIFTED)
BEQ div_by_zero
<rest of code>
div_by_zero:
MOV A1, LR
BL _div_zero
MOV r0, #10 ; DIVIDE BY ZERO RETURNS ZERO
POP {r2-r4}
MOV pc, lr
.end
=====================
resulting list file
=====================
37 00000000 U$DIV:
38 00000000 B41C U$MOD: PUSH {r2-r4}
39
40 00000002 1C0A MOV dvs, r1
41 00000004 D044 BEQ div_by_zero
42
126 00000090 div_by_zero:
127
145
==> 146 00000090 4670 MOV A1, LR
==> 147
==> 148 00000092 F7FF! BL $div_zero
==> 00000094 FFB5
149
152
153 00000096 200A MOV r0, #10
154 00000098 BC1C POP {r2-r4}
155
157
158 0000009a 46F7 MOV pc, lr
159
160 .end
=====================
According to the PDF I have TMS470R1x User’s Guide
A value may be transferred from a register in the range R0-R7 (a Lo register) to a Hi register, and from a Hi register to a Lo register, using special variants of the MOV instruction. Hi register values can also be compared against or added to Lo register values with the CMP and ADD instructions. See Section 5.5, Format 5: Hi register operations/branch exchange, 5-14.
Is this the proper usage of transferring a HI reg (LR/R14) to a LO reg (A1)? That PDF has the opcode for MOV but doesnt say what the hex output for this “special” mode should be so I cant cross reference this with my list file to see if its generating what I think it should.
Am I going about this the right way? Is this how to pass the LR back to a function in 16 bit?