2

I don't understand why the C51 compiler (in Keil) convert C source to this assembly language code: (As p is a pointer to unsigned char)

;   p++;
            ; SOURCE LINE # 216
    MOV     R3,pDisplay?253
    INC     pDisplay?253+02H
    MOV     A,pDisplay?253+02H
    MOV     R2,pDisplay?253+01H
    JNZ     ?C0090
    INC     pDisplay?253+01H

As R3 and R2 wasn't used in the next lines of the program.
Why do compiler make these lines
MOV R3,pDisplay?253,
MOV R2,pDisplay?253+01H?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Gamcheong
  • 41
  • 2

1 Answers1

9

Welcome to 1980s "state of the art" code generation for 8-bit target processors. What the code is doing is "noting the value" of p before incrementing it. That's necessary when the postincrement operator is used in a surrounding expression; and not optimized away by subsequent passes of the compiler.

Try p += 1;, or even ++p; instead. Odds are that one or both of those will generate better code because there is no "note the value before" semantics to get in the code generator's way.

[This is how I got into the minority, by the way, using ++i in for () loops rather than the more common i++.]

Mike Housky
  • 3,959
  • 1
  • 17
  • 31
  • I've got it. And I tried the code like `p0 = p++;` and found Keil used a function in the library `?C?CLDPTR` to load R1/R2/R3 data to A and finally passed A to p0.
    Thank you.
    – Gamcheong Jun 27 '18 at 02:04
  • @Gamcheong That's an example where the "note the previous value" is important. It's equivalent to `p0 = p1, p1 += 1;` and there's no reason for any compiler to generate better code with the longer explicit version. If cycles or code bytes matter, avoid `p1++` for just incrementing without using the previous value of `p1`. – Mike Housky Jun 28 '18 at 17:03