I am working on some disassembly from an NEC 78K0R. Most functions have parameters passed in registers, but there are some functions that have compile time defined parameters passed using a method I have not seen before.
Execution of instructions is from flash.
The function, 0x4c4, is called as follows:
027d9 fdc404 CALL !4C4H
027dc 02 ? ?
027dd 75 MOV D,A
The return address is set to 0x27dc and put into the stack.
The function itself is as follows:
// Entry point from call
004c4 c1 PUSH AX
004c5 c3 PUSH BC
004c6 c5 PUSH DE
004c7 c7 PUSH HL
// Get the stack pointer into HL
004c8 aef8 MOVW AX,SP
004ca 16 MOVW HL,AX
004cb c7 PUSH HL
// Preserve the ES (extended segment) register used for addressing
004cc 8efd MOV A,ES
004ce c1 PUSH AX
// Retreive SP + 0x0A - this is the ES part of the return address
004cf 8c0a MOV A,[HL+0AH]
004d1 9efd MOV ES,A
// Retreive SP + 0x8 - this is the lower two bytes of return address
004d3 ac08 MOVW AX,[HL+8H]
004d5 16 MOVW HL,AX
// Take the contents of memory from the return address into A
004d6 118b MOV A,ES:[HL]
// Not relevant to question
004d8 74 MOV E,A
004d9 c0 POP AX
004da 9efd MOV ES,A
004dc 5500 MOV D,#0H
// HL is the original return address - shift up one to skip to instruction and store back into stack
004de a7 INCW HL
004df 17 MOVW AX,HL
004e0 c6 POP HL
004e1 bc08 MOVW [HL+8H],AX
So, in short - the parameter 02 is stored in the flash memory in the next address. This is retrieved by using the return address from the stack, and then the return address in the stack in incremented by one so that we get to the next real instruction.
The function shifts about the contents of the stack, but I do not think this is material to the problem.
I've not seen this method used before - it's rather curious. I can't work out why it would be done - that's a lot of instructions required, as compared to doing:
MOV A,#2
CALL !4c4H
<use A as parameter>
Has anyone got any insights to why this has been done like this?
Edit
As requested, the entire function:
004c4 c1 PUSH AX
004c5 c3 PUSH BC
004c6 c5 PUSH DE
004c7 c7 PUSH HL
004c8 aef8 MOVW AX,SP
004ca 16 MOVW HL,AX
004cb c7 PUSH HL
004cc 8efd MOV A,ES
004ce c1 PUSH AX
004cf 8c0a MOV A,[HL+0AH]
004d1 9efd MOV ES,A
004d3 ac08 MOVW AX,[HL+8H]
004d5 16 MOVW HL,AX
004d6 118b MOV A,ES:[HL]
004d8 74 MOV E,A
004d9 c0 POP AX
004da 9efd MOV ES,A
004dc 5500 MOV D,#0H
004de a7 INCW HL
004df 17 MOVW AX,HL
004e0 c6 POP HL
004e1 bc08 MOVW [HL+8H],AX
004e3 17 MOVW AX,HL
004e4 25 SUBW AX,DE
004e5 bef8 MOVW SP,AX
004e7 c5 PUSH DE
004e8 14 MOVW DE,AX
004e9 320c00 MOVW BC,#0CH
004ec 8b MOV A,[HL]
004ed 99 MOV [DE],A
004ee a7 INCW HL
004ef a5 INCW DE
004f0 b3 DECW BC
004f1 6171 XOR A,A
004f3 616a OR A,C
004f5 616b OR A,B
004f7 dff3 BNZ $4ECH
004f9 c2 POP BC
004fa aef8 MOVW AX,SP
004fc 040c00 ADDW AX,#0CH
004ff 14 MOVW DE,AX
00500 3620fe MOVW HL,#0FE20H
00503 fd6104 CALL !461H
00506 c6 POP HL
00507 c4 POP DE
00508 c2 POP BC
00509 c0 POP AX
0050a d7 RET
Sub 461 called from above:
00461 c1 PUSH AX
00462 c3 PUSH BC
00463 61dd PUSH PSW
00465 17 MOVW AX,HL
00466 25 SUBW AX,DE
00467 de18 BNC $481H
00469 37 XCHW AX,HL
0046a 03 ADDW AX,BC
0046b 37 XCHW AX,HL
0046c 35 XCHW AX,DE
0046d 03 ADDW AX,BC
0046e 35 XCHW AX,DE
0046f 61cd POP PSW
00471 b7 DECW HL
00472 b5 DECW DE
00473 8b MOV A,[HL]
00474 99 MOV [DE],A
00475 b3 DECW BC
00476 6171 XOR A,A
00478 616a OR A,C
0047a 616b OR A,B
0047c dff3 BNZ $471H
0047e ee1000 BR $!491H
00481 61cd POP PSW
00483 c5 PUSH DE
00484 c7 PUSH HL
00485 8b MOV A,[HL]
00486 99 MOV [DE],A
00487 a7 INCW HL
00488 a5 INCW DE
00489 b3 DECW BC
0048a 13 MOVW AX,BC
0048b 6168 OR A,X
0048d dff6 BNZ $485H
0048f c6 POP HL
00490 c4 POP DE
00491 c2 POP BC
00492 c0 POP AX
00493 d7 RET
And also the pre/post of the call:
024fe c5 PUSH DE
024ff fdc404 CALL !4C4H
02502 06
02503 9d24 MOV 0FFE24H,A
02505 33 XCHW AX,BC
02506 bd20 MOVW 0FFE20H,AX