hello everyone, i have a doubt regarding conversion from C to assembly when using the disassembly window in keil uv3. now int x; converts to MOV x(0x05),0x00; in assembly language. i dont know what the notation x(0x05) means. ideally it should be mov r0,0x00; mov r1,0x00; since i need to allot 16 bits. kindly help me out here.
The Disassembly window does not convert from 'C' to assembly.
"Assembly" is the process of translating from Assembler source to binary; "Disassembly", then, is the process of translating from binary back to Assembler source.
What the debugger then does is to find ther closest 'C' source line to the disassembled address, and displays that. There is no actual "conversion" betweene 'C' and assembler - it just a matter of displaying the closest source line.
This is why things get so confusing with optimised code!
IF you want to see what assembler the compiler has generated, then use assembler listing option: http://www.keil.com/support/man/docs/uv4/uv4_dg_listing.htm www.keil.com/.../uv4_ca_spec_seprte_fldr.htm
int x;
converts (sic) to
MOV x(0x05),0x00
I think you're probably misinterpreting the display there!
Note that a single 'C' line is likely to result in may assembler instructions - you have probably shown just the first assembler instruction there.
"i dont know what the notation x(0x05) means"
x is the 'C' symbol name; (0x05) is the disassembled binary "value" of the symbol.
Note that the "value" of the symbol here is its address.
Note also that the disassembler just knows the addres, but there may be many 'C' symbols that have an address of 0x05 - so this "decoding" is often unhelpful.
ideally it should be
mov r0,0x00; mov r1,0x00;
You cannot force a compiler - any compiler - to use specific registers or instructions.
If the use of specific registers or instructions is important to you, then you need to write in assembler!
As already noted, if you want to see what assembler the compiler has generated, then use assembler listing option when you compile.
hey, my post is a bit long but i am actually interested in variable initialization only. it will clarify lot of things
here is the c program:
#include<reg51.h> int x,y,temp; void main() { x=12; y=05; if(x<y){ temp=x; x=y; y=temp; } x=x-y; }
here is the disassembly window program:
C:0x0000 020040 LJMP STARTUP1(C:0040) 3: void main() 4: { 5: 6: x=12; C:0x0003 750A00 MOV x(0x0A),#0x00 C:0x0006 750B0C MOV 0x0B,#y(0x0C) 7: y=05; C:0x0009 750C00 MOV y(0x0C),#0x00 C:0x000C 750D05 MOV 0x0D,#0x05 8: if(x<y) C:0x000F C3 CLR C C:0x0010 E50B MOV A,0x0B C:0x0012 950D SUBB A,0x0D C:0x0014 E50C MOV A,y(0x0C) C:0x0016 6480 XRL A,#P0(0x80) C:0x0018 F8 MOV R0,A C:0x0019 E50A MOV A,x(0x0A) C:0x001B 6480 XRL A,#P0(0x80) C:0x001D 98 SUBB A,R0 C:0x001E 5012 JNC C:0032 9: { 10: temp=x; C:0x0020 850A08 MOV temp(0x08),x(0x0A) C:0x0023 850B09 MOV 0x09,0x0B 11: x=y; C:0x0026 850C0A MOV x(0x0A),y(0x0C) C:0x0029 850D0B MOV 0x0B,0x0D 12: y=temp; C:0x002C 85080C MOV y(0x0C),temp(0x08) C:0x002F 85090D MOV 0x0D,0x09 13: } 14: x=x-y; C:0x0032 C3 CLR C C:0x0033 E50B MOV A,0x0B C:0x0035 950D SUBB A,0x0D C:0x0037 F50B MOV 0x0B,A C:0x0039 E50A MOV A,x(0x0A) C:0x003B 950C SUBB A,y(0x0C) C:0x003D F50A MOV x(0x0A),A 15: }
here is the lst file :
; FUNCTION main (BEGIN) ; SOURCE LINE # 3 ; SOURCE LINE # 4 ; SOURCE LINE # 6 0000 750000 R MOV x,#00H 0003 75000C R MOV x+01H,#0CH ; SOURCE LINE # 7 0006 750000 R MOV y,#00H 0009 750005 R MOV y+01H,#05H ; SOURCE LINE # 8 000C C3 CLR C 000D E500 R MOV A,x+01H 000F 9500 R SUBB A,y+01H 0011 E500 R MOV A,y 0013 6480 XRL A,#080H 0015 F8 MOV R0,A 0016 E500 R MOV A,x 0018 6480 XRL A,#080H 001A 98 SUBB A,R0 001B 5012 JNC ?C0001 ; SOURCE LINE # 9 ; SOURCE LINE # 10 001D 850000 R MOV temp,x 0020 850000 R MOV temp+01H,x+01H ; SOURCE LINE # 11 0023 850000 R MOV x,y 0026 850000 R MOV x+01H,y+01H ; SOURCE LINE # 12 0029 850000 R MOV y,temp 002C 850000 R MOV y+01H,temp+01H ; SOURCE LINE # 13 002F ?C0001: ; SOURCE LINE # 14 002F C3 CLR C 0030 E500 R MOV A,x+01H 0032 9500 R SUBB A,y+01H 0034 F500 R MOV x+01H,A 0036 E500 R MOV A,x 0038 9500 R SUBB A,y 003A F500 R MOV x,A ; SOURCE LINE # 15 003C 22 RET ; FUNCTION main (END)
in the disassembly program there is a line MOV x(0x0A),#0x00; MOV 0x0B,#y(0x0C); . i believe 0x0a is the RAM address and is bank 01's R2 register. but why write x(0x0A) when we can write MOV 0x0A#,0x00? and in the next line address 0x0B is written directly. also in lst file MOV x,#0x00 is written but its value i.e 0x0a is not specified. please help me on the variable initialization part.
Most assembler programmers makes use of labels - it's not good to use numeric values for addresses when writing code. What if you want to switch address? Add a variable? Remove a variable?
So if humans normally names the addresses used - why shouldn't the compiler be good enough to do the same when it generates assembler output?
Programming isn't about using the fewest numbers of characters in the source code. It's about writing the most human-readable and understandable code that still performs well.
If I do write assembler code, and need a 16-bit variable on an 8-bit processor, I would use "var", "var+1" to access the two memory cells. The only trick remaining then is to make it clear if the variable is stored big-endian eller little-endian.