In the following code: ******************************************** #include <REG51.H> unsigned char rem(unsigned char d1,unsigned char d2) { B=d2; ACC=d1; #pragma asm DIV AB; #pragma endasm return B; } void main(void) { while(1) { unsigned char x,y,z; P0=255; x=65; y=10; z=rem(x,y); P0=z; } } ***************************************** I noticed that the instruction d1=ACC is not converted into assembly (Keil ignores this line). Is this any reason behind that?..How can I solve the problem? Thanks
Thanks Oleg for that info. The problem is I didn't know how to get the remainder using C. I find your help so valuable Many thanks again.
hi, why do you try to play with ASM for such purposes? Next C lines produce the same result:
unsigned char div(unsigned char x, unsigned char y) { return (x/y); } unsigned char rem(unsigned char x, unsigned char y) { return (x%y); }
unsigned char div(unsigned char x, unsigned char y) MOV A,R7 MOV B(0xF0),R5 DIV AB MOV R7,A RET unsigned char rem(unsigned char x, unsigned char y) MOV A,R7 MOV B(0xF0),R5 DIV AB MOV R7,B(0xF0) RET
All updates are free as long as your product maintenance is not expired. Updates are available from http://www.keil.com/update/c51.asp. Jon
Thanks for the advice..I am not sure if this is free though
I ma using version 7.00 and the line ACC=d1 is not converted..It drives me nuts.. Why don't you download the latest update? Jon
I ma using version 7.00 and the line ACC=d1 is not converted..It drives me nuts..
I noticed that the instruction d1=ACC is not converted into assembly (Keil ignores this line). What version of the tools do you use? I'm using V7.10 and it generates the following SRC file.
; unsigned char rem(unsigned char d1,unsigned char d2) RSEG ?PR?_rem?MAIN _rem: USING 0 ; SOURCE LINE # 3 ;---- Variable 'd2?041' assigned to Register 'R5' ---- ;---- Variable 'd1?040' assigned to Register 'R7' ---- ; { ; SOURCE LINE # 4 ; B=d2; ; SOURCE LINE # 5 MOV B,R5 ; ACC=d1; ; SOURCE LINE # 6 MOV A,R7 ; ; #pragma asm ; DIV AB; DIV AB; ; #pragma endasm ; ; return B; ; SOURCE LINE # 12 MOV R7,B ; } ; SOURCE LINE # 13 ?C0001: RET ; END OF _rem
Thanks, this solved it... By the way: Is there any easy way to get the remainder of unsigned division? Thanks again
I don't have my C51 toolchain ready at hand to check this, but something like:
unsigned char rem(unsigned char d1,unsigned char d2) { #pragma asm MOV B,R5 MOV A,R7 DIV AB MOV R7,B RET #pragma endasm }
Trying to utilize commonly used registers like ACC, R0-R7, B, DPTR, SP, etc. directly from C is not a good idea. You should learn the compiler's calling conventions and register usage, then expand the scope of your 'asm' pragmas and code anything that deals with registers in assembly.
View all questions in Keil forum