We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
This is a function that i wrote using assembly:
; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;NAME: clearXdataNBytes ;FUNCTION: ; This functioin clear n bytes in the external ;space starting with the address specified ;PARAMETERS: ; B(unsigned byte)---the numbers of bytes to ;be cleared! ; DPTR(unsigned word)---the starting address ;RETURNS: None! ;PROLOGUE BY CALLING: ; PUSH DPL,PUSH ;DPH,PUSH B,MOV DPTR,#startAddr,MOV ;B,#nbytes! ;EPILOG BY CALLING:NONE! ;NOTES: The MAX number of bytes to be cleared is 255!And,we use A as temporary variables!There is no check if the external space pointed by DPTR is legal! ;EXAMPLES: ; ... ; //Prologue: ; PUSH DPL ; PUSH DPH ; PUSH B ; //Move the parameters ; MOV DPTR,#startAddr ; MOV B,#200 ; //Call this function ; LCALL clearXdataNBytes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; clearXdataNBytes: PUSH ACC CLR A clearXdataNBytes_LOOP: MOVX @DPTR,A INC DPTR DJNZ B,LOOP POP ACC POP B POP DPH POP DPL RET
well,about PUSH ACC CLR A ... POP ACC POP B POP DPH POP DPL
if i call this function in a loop,it seems that these codes are executed repeatedly,and it seems that it's an overhead in my system?Is that possible or is there some wrong thinking?How can i solve it?!
How can this code be generic, i.e. not related to any processor architecture? Do you really think any processor can handle your assembler code?
You (?) have written a function. If you call this function from a loop, the code in the function will be processed identically as if you call this function only once.
If you need to clear more memroy, then you can write another assembler function that performs a push/pop and then uses two nested loops for the clear.
HI.
mistake number won. u pop more than u push!
mistake number too. u do not need to preserve ACC or B or DPTR for routine called by C51
Always yo're freind.
Zeusti.
i think it is C51. sorry if not.
Well of course they are - that is the whole point of a loop!
Not if you follow the stated Prologue:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;NAME: clearXdataNBytes ;FUNCTION: ; This functioin clear n bytes in the external ; space starting with the address specified ;PARAMETERS: ; B(unsigned byte)---the numbers of bytes to ;be cleared! ; DPTR(unsigned word)---the starting address ;RETURNS: None! ;PROLOGUE BY CALLING: ; PUSH DPL,PUSH ;DPH,PUSH B,MOV DPTR,#startAddr,MOV ;B,#nbytes! ;EPILOG BY CALLING:NONE! ;NOTES: The MAX number of bytes to be cleared is 255... ;EXAMPLES: ; ... ; //Prologue: ; PUSH DPL ; PUSH DPH ; PUSH B ; //Move the parameters ; MOV DPTR,#startAddr ; MOV B,#200 ; //Call this function ; LCALL clearXdataNBytes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
How can this code be generic, i.e. not related to any processor architecture? Do you really think any processor can handle your assembler code? I wrote it for 51
You (?) have written a function. If you call this function from a loop, the code in the function will be processed identically as if you call this function only once. What do you mean?
If you need to clear more memroy, then you can write another assembler function that performs a push/pop and then uses two nested loops for the clear. you mean if i want to avoid this situation that i described,only write another function like you said!?
thank you!!!
but
push push push call push .. .. pop pop pop pop ret
looks very very very bad to me for this situetion.
I just want to make this function reentrant by doing that way!!!
Why to you require the caller to perform some of the work then? A reentrant function should be self-sufficient, and not require the caller to hold the hand.
It should be enough for the caller to initialize the parameters. The rest is up to the called function.
?,explain it in more detail,please!
Explain what?
A reentrant function that uses DPL/DPH should save them. A reentrant function that uses B should save it. The function should not require someone else to do it or it will not be reentrant.
Next thing is that a prologue is the entry code for a function - not how you call it.
In this case, you use DPH/DPL/B for parameter passing. That means that your function can't be reentrant, and should not try to be. It is up to the calling function to be reentrant (if required). That means that the calling function should contain both the push and the pop. If the calling function has both push and pop, then the calling function can do:
push DPH push DPL push B MOV DPTR,#startAddr MOV B,#200 LCALL clearXdataNBytes MOV DPTR,#startAddr2 MOV B,#100 LCALL clearXdataNBytes ... pop B pop DPL pop DPH
When you mix the responsibility of push and pop between multiple functions, then you get into the trouble that a loop calling the function will have to repeat the save for each call.
So,how can i write a reentranted function that uses some registers to pass parameters?!
I think it's ok that using the registers to realize reentrant function,I am confused because of the POPs in the "reentrant function", i placed them at the end of it,so i can reduce the code space,because these codes are scattered all over if this function called all over.