User:Moiree/Pointers in assembler vs. C (cc65)
From C64-Wiki
Jump to navigationJump to search
These examples are for example purpose only.
Why to start coding in C rather than in BASIC | |
---|---|
!to "ptest0.asm" *=$1000 |
void main(void) { |
COLORRAM = $D800 |
#define COLORRAM ((unsigned char*) 0xd800) |
colorram_p = $fc |
unsigned char *ColorRAM_p; |
lda #$d7 sta $fe lda #$01 ldy #$e7 ldx #$db sty colorram_p stx colorram_p+1 |
ColorRAM_p = COLORRAM; |
ldy #$00 .loop: sta (colorram_p),y dec colorram_p bne .loop dec colorram_p+1 ldx colorram_p+1 cpx $fe beq .end lda #$01 jmp .loop .end: rts |
unsigned int i; for (i = 0; i < 1000; ++i) { *(ColorRAM_p++) = 1; } |
} |
Comparison of above asm code vs. what cc65 -Oi -Os -Or produced | |
---|---|
COLORRAM = $D800 colorram_p = $fc lda #$d7 sta $fe lda #$01 ldy #$e7 ldx #$db sty colorram_p stx colorram_p+1 ldy #$00 .loop: sta (colorram_p),y dec colorram_p bne .loop dec colorram_p+1 ldx colorram_p+1 cpx $fe beq .end lda #$01 jmp .loop .end: rts |
.segment "BSS" _ColorRAM_p: .res 2,$00 _i: .res 2,$00 ; --------------------------------------------------------------- ; void __near__ main (void) ; --------------------------------------------------------------- .segment "CODE" .proc _main: near .segment "CODE" ldx #$D8 lda #$00 sta _ColorRAM_p stx _ColorRAM_p+1 sta _i sta _i+1 L0006: lda _i+1 cmp #$03 bne L000D lda _i cmp #$E8 L000D: bcs L0007 lda _ColorRAM_p ldx _ColorRAM_p+1 sta regsave stx regsave+1 clc adc #$01 bcc L0012 inx L0012: sta _ColorRAM_p stx _ColorRAM_p+1 lda #$01 ldy #$00 sta (regsave),y inc _i bne L0006 inc _i+1 jmp L0006 L0007: rts .endproc |
Lets write C like assembler and see what cc65 does with it (optimizations all on!)
#define COLORRAM ((unsigned char*) 0xd800) unsigned char *ColorRAM_p; void main(void) { ColorRAM_p = COLORRAM; for ( ColorRAM_p = (unsigned char *) 0xdbe7; ColorRAM_p == (unsigned char *) 0xd7ff; *( --ColorRAM_p ) = 1 ); } | |
.segment "BSS" _ColorRAM_p: .res 2,$00 _i: .res 2,$00 ; --------------------------------------------------------------- ; void __near__ main (void) ; --------------------------------------------------------------- .segment "CODE" .proc _main: near .segment "CODE" ldx #$D8 lda #$00 sta _ColorRAM_p stx _ColorRAM_p+1 sta _i sta _i+1 L0006: lda _i+1 cmp #$03 bne L000D lda _i cmp #$E8 L000D: bcs L0007 lda _ColorRAM_p ldx _ColorRAM_p+1 sta regsave stx regsave+1 clc adc #$01 bcc L0012 inx L0012: sta _ColorRAM_p stx _ColorRAM_p+1 lda #$01 ldy #$00 sta (regsave),y inc _i bne L0006 inc _i+1 jmp L0006 L0007: rts .endproc |
.segment "BSS" _ColorRAM_p: .res 2,$00 ; --------------------------------------------------------------- ; void __near__ main (void) ; --------------------------------------------------------------- .segment "CODE" .proc _main: near .segment "CODE" ldx #$D8 lda #$00 sta _ColorRAM_p stx _ColorRAM_p+1 ldx #$DB lda #$E7 sta _ColorRAM_p stx _ColorRAM_p+1 L0006: lda _ColorRAM_p+1 cmp #$D7 bne L0007 lda _ColorRAM_p cmp #$FF bne L0007 lda _ColorRAM_p sec sbc #$01 sta _ColorRAM_p bcs L0010 dec _ColorRAM_p+1 L0010: ldx _ColorRAM_p+1 sta ptr1 stx ptr1+1 lda #$01 ldy #$00 sta (ptr1),y jmp L0006 L0007: rts .endproc |
So better write C like C, the CC65 compiler seems good enough! |
common sense
lda #01 ldy #249 - sta $d800,y sta $d800+250,y sta $d800+500,y sta $d800+750,y dey bpl - rts