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.
some time c user do shift for mul and divide and some time u write byte to byte then not require any carry for me in asm i do two shift mul 4 i do it with c51 ypos3 = ypos>>3; ; SOURCE LINE # 237 MOV A,R5 RRC A RRC A ANL A,#01FH ;---- Variable 'ypos3?1255' assigned to HOW DO IT IN C51 WITHOUT MOV A,R5 ANL A,#01FH ??
I am not sure that I really understand your question, but I hope that this helps. In general, when you write a C statement that includes arithmetic operations multiply, divide and modulo where one operand is a constant that is 2^n, the Keil compiler is good at converting the operation to the shift, SWAP and mask equivalent. In most cases, the programmer is best advised to use the operators that make the best sense to a human reader and leave the rest to the compiler. You cannot tell the compiler to do things any particular way. The only alternative is to resort to assembly language... It is possible to achieve shift operations by multiplying or dividing. In cases when the number of bits to shift is variable, this can work out faster than bit shifting. To shift n bits to the left or right, multiply or divide by 2^n. When shifting by a variable number of bits, Keil C51 does not do so well. Keil also offers some some "intrinsic" functions for doing rolls, these are not efficient when shifting for more than about 3 bits. In both these cases, some hand optimisation may be worthwhile. This is particularly true when rolling long variables. See: http://www.keil.com/forum/docs/thread1252.asp for an example. The methods used in the example can easily be adapted to provide solutions that shift or roll, longs, ints or chars.
THX
Hi, the main reason for the ANL A,01Fh is simply, that RRC shifts the carry bit into the accu MSB. So after 3 RRC you have the 3 MSBs set to some "random" value, which is NOT what the C-statement meant. The MOV A,R5 is necessary, because the 8051 can just shift the accu (and not some register). If you're using assembler, ANY shift can be done in TWO statements (plus the ANL), provided, data is stored in the accu already. bis die Tage... Mathias
For this C code:
unsigned char t; ... t = t << 3; t = _crol_(t,3);
; SOURCE LINE # 988 ; SOURCE LINE # 991 0005 900000 R MOV DPTR,#t 0008 E0 MOVX A,@DPTR 0009 FF MOV R7,A 000A 33 RLC A 000B 33 RLC A 000C 33 RLC A 000D 54F8 ANL A,#0F8H 000F FF MOV R7,A 0010 F0 MOVX @DPTR,A ; SOURCE LINE # 993 0011 7803 MOV R0,#03H 0013 08 INC R0 0014 8001 SJMP ?C0090 0016 ?C0089: 0016 23 RL A 0017 ?C0090: 0017 D8FD DJNZ R0,?C0089 0019 900000 R MOV DPTR,#t 001C F0 MOVX @DPTR,A
n%8 0 NOP 1 RL A 2 RL A, RL A 3 SWAP Acc, RR A 4 SWAP Acc 5 SWAP Acc, RL A 6 RR A, RR A 7 RR A