You could simplify this to: LDR pc, main_address How are you checking the pc value? When running code the PC points at the instruction being fetched - not the one being executed.
LDR pc, main_address
reset_handler: # copy from flash(0x00000000) to ram eor r0, r0 ldr r1, ram_start ldr r2, ram_end sub r2, r2, r1 1: ldr r3, [r0], #4 str r3, [r1], #4 subs r2, #4 bne 1b # install a stack ldr sp, stack_top mov fp, sp # branch to main ldr pc, main_address b reset_handler ram_start: .extern __ram_start .word __ram_start // == 0x40000100ram_end: .extern __ram_end .word __ram_end // == 0x40000200stack_top: .word __ram_end + 0x1000 main_address: .extern main .word main