paulw 发表于 2007-5-8 10:57:31

由ICCAVR编译mega128的mp文件,为何从0x06F1执行程序?

NOTE: AVR Code addresses are word addresses

All other addresses (including ones in FLASH) are byte addresses



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                           lit   008C   0D0E =   3342. bytes (rel,con,rom)



       AddrGlobal Symbol

      -------------------------------------

       008C_char14

       008C__lit_start

       016C_char16

       022C_char24

       073C_char32

       083C_num32

       0ABC_char8_1

       0B5C_char8_2

       0BDA_symble1_8

       0BEA_symble2_8

       0C06_num8

       0CA6_num8_3

       0CE6_num8_2

       0D72_Channel

       0D7A_DecimalHex

       0D9A__lit_end



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                           idata   0D9A   0048 =   72. bytes (rel,con,rom)



       AddrGlobal Symbol

      -------------------------------------

       0D9A__idata_start

       0DE2__idata_end



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                            text   0DE2   3126 =12582. bytes (rel,con,rom)



       AddrGlobal Symbol

      -------------------------------------

       06F1__text_start

       06F1__start

       0711_exit

       0712_main

       0949_uart0_init

       0956_uart0_rx_isr

       0A04_uart0_udre_isr

       0A62_uart0_tx_isr

       0A6B_SendUpdateData

       0AB1_SendUpdateKey

       0AEA_Port_init

       0B07_Sys_init

       0B0D_watchdog_init

       0B13_Switch_driver

       0B47_Delay

       0B5E_Delay1

       0B6C_E_to_P

       0B84_SampleStart

       0B8F_SampleStop

       0B93_spi_stc_isr

       0BF1_Ad_Sample

       0C08_KEYscan

       0C85_Timer2_init

       0C92_Timer2OvfIsr

       0CA0_Timer2Stop

       0CA3_Timer2Start

       0CA6_AD_To_Disp1

       0CE2_AD_To_Disp2

       0D23_WS_calculate

       0D6E_ttvalue

       0D85_kvalue

       0DC1_pmdisp_calcu

       0E24_Wr_Data

       0E39_Wr_Ctrl

       0E56_RD_Status

       0E6D_RD_Datas

       0E84_WRCTRL_2

       0E91_WRCTRL

       0E99_LCM_init

       0ED5_WRCONST_auto

       0EDE_RDATA_auto

       0EE5_ADDRES_change

       0EF4_RDADDRES_auto

       0F11_WRADDRES_auto

       0F2C_Dis_All

       0F4B_Clrram

       0F67_Clrgraph

       0F83_Clr_Part

       0FA4_Dis_zimo

       0FEF_Dis_char16_16

       101E_Dis_char16_14

       1043_Dis_char16_32

       1072_Dis_char8_14

       109C_Dis_char24_24

       10C1_Dis_char16_24

       10E6_Dis_char8_16

       1110_Put_pixel

       1131_Clear_pixel

       1152_Clear_liney

       1164_Line_x

       117E_Line_y

       1198_Draw_line

       11E2_Draw_on_line

       1279_Draw_fullline

       135A_Dis_coordinate

       137A_Dis_xcoordinate

       1399_Dis_ycoordinate

       13B8_Dis_FIRSTscreen

       13D6_Dis_EValue

       1485_Dis_WMValue

       14EE_Dis_PpMValue

       17B7_Dis_TTValue

       1817_Dis_WorkState

       185B_Dis_TUnitage

       1902_Dis_PUnitage

       19CA_Dis_SndScreen

       1A3B_Snd_Refurbish

       1AA9_Dis_ESetScree

       1B1D_Dis_PSetScree

       1B91_Dis_WSetScree

       1C36_Dis_TrdScreen

       1C42_Trd_Refurbish

       1C64_KEYanswer

       1E1Dpush_arg4

       1E1Fpush_arg2

       1E22mod16u

       1E24div16u

       1E25xdiv16u

       1E3Ediv32u

       1E40mod32u

       1E44div32s

       1E46mod32s

       1E71long_div_prolog

       1E84long_div_epilog

       1E93tst_R16_R19

       1E98tst_R24_R27

       1E9Dneg_R16_R19

       1EA6neg_R24_R27

       1EAFmod8u

       1EB1div8u

       1EB2xdiv8u

       1EC7empy16s

       1ED7empy32u

       1ED7empy32s

       1F07pop_gset2

       1F0Apop_gset3

       1F0Dpop_gset4

       1F10pop_gset5

       1F13push_gset1

       1F16pop_gset1

       1F17pop

       1F2Apush_gset2

       1F2Epush_gset3

       1F32push_gset4

       1F36push_gset5

       1F3Along_prolog

       1F48long_epilog

       1F53tstzero1

       1F59tstzero2

       1F5Flsl16

       1F66lsl32

       1F72lsl8

       1F78lsr32

       1F84__text_end



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                            data   0100   0048 =   72. bytes (rel,con,ram)



       AddrGlobal Symbol

      -------------------------------------

       0100__data_start

       0100_MainState

       0101_EZeroNum

       0102_EmData

       0104_Pulse_flag

       0105_ad_enable_flag

       0106_ESetRange

       0107_PSetRange

       0108_EHoldflag

       0109_WSetwave

       010A_TimeUnit

       0115_PowerUnit

       011C_WorkState

       011D_SetState

       011E_Disp_change

       011F_Trd_Disp_change

       0120_P_Unitage

       0122_TmpKey

       0123_KeyTime

       0124_KeyState

       0125_DispState

       0126_UartReceiveNum

       0127_UartReceiveDataNum

       0128_UartSendNum

       0129_UartRecChk

       012A_UartSendChk

       012B_UartLength

       012C_UartRecieveOver

       012D_UartSendOver

       012E_ADS7844State

       012F_numx

       0133_numy

       0137_Wm_value

       0139_E_Value

       013B_P_Value

       013D_EZEROsum

       013F_Pm_bit_nub

       0140_tmppm

       0144_tmpk

       0148__data_end



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                           bss   0148   0837 =   2103. bytes (rel,con,ram)



       AddrGlobal Symbol

      -------------------------------------

       0148__bss_start

       0148_ADResult

       0158_Rslt16

       015A_UartSend

       0163_UartSendData

       0165_UartSendBuffer

       0183_UartRecBuffer

       018D_EZeroData

       01F1_Curve

       097D_Adrs

       097F__bss_end



Area                               Addr   Size   Decimal Bytes (Attributes)

--------------------------------   ----   ----   ------- ----- ------------

                        vector   0000   0054 =   84. bytes (abs,ovr,rom)



Files Linked      [ module(s) ]



C:\icc\lib\crtatmega.o        [ crtatmega.s ]

6312a.o        [ _6312a.c ]

<library>        [ asave.s, div16u.s, div32.s, div8u.s, emul16s.s, emul32.s, gpop2.s, gpop3.s, gpop4.s, gpop5.s, gpush.s ]

[ gpush2.s, gpush3.s, gpush4.s, gpush5.s, longutil.s, lsl16.s, lsl32.s, lsl8.s, lsr32.s ]



User Global Definitions



ram_end = 0x10ff

hwstk_size = 0x10



User Base Address Definitions



func_lit = 0x8c

data = 0x100

eeprom:1.4096

paulw 发表于 2007-5-8 11:16:13

首先,程序烧入mega128中能够正常运行,一切正常;其次,我的好奇心作怪,喜欢钻个究竟,当调试程序时发现,复位后程序不是从中断向量表后地址0x48开始运行,在打开mp文件、lst文件后,发现在0x48到启动代码之间为空白,百思不解,lst文件详见下:

__text_start:

__start:

    06F1 EFCF      LDI        R28,0xFF

    06F2 E1D0      LDI        R29,0x10

    06F3 BFCD      OUT        0x3D,R28

    06F4 BFDE      OUT        0x3E,R29

    06F5 51C0      SUBI        R28,0x10

    06F6 40D0      SBCI        R29,0

    06F7 EA0A      LDI        R16,0xAA

    06F8 8308      STD        Y+0,R16

    06F9 2400      CLR        R0

    06FA E4E8      LDI        R30,0x48

    06FB E0F1      LDI        R31,1

    06FC E019      LDI        R17,0x9

    06FD 37EF      CPI        R30,0x7F

    06FE 07F1      CPC        R31,R17

    06FF F011      BEQ        0x0702

    0700 9201      ST        R0,Z+

    0701 CFFB      RJMP        0x06FD

    0702 8300      STD        Z+0,R16

    0703 E9EA      LDI        R30,0x9A

    0704 E0FD      LDI        R31,0xD

    0705 E0A0      LDI        R26,0

    0706 E0B1      LDI        R27,1

    0707 E01D      LDI        R17,0xD

    0708 3EE2      CPI        R30,0xE2

    0709 07F1      CPC        R31,R17

    070A F021      BEQ        0x070F

    070B 95C8      LPM

    070C 9631      ADIW        R30,1

    070D 920D      ST        R0,X+

    070E CFF9      RJMP        0x0708

    070F 940E0712CALL        _main

_exit:

    0711 CFFF      RJMP        _exit

_main:

p                  --> Y+3

j                  --> Y+3

i                  --> Y+3

sum                  --> R10

tmpt               --> R10

aveezerodata         --> R10

tmpc               --> Y+2

ADetmp16             --> R14

uarttmp            --> Y+7

timer0               --> Y+6

ADwtmp16             --> R12

    0712 9728      SBIW        R28,0x8

FILE: D:\cx\atmega128\IccAvr6.3\scr\main.c

(0001) //#include "include.h"

(0002) /*******************************************************************************

(0003) *   函数功能:主函数

(0004) *   函数参数:无

(0005) *   函数返回:无

(0006) *   备    注:无

(0007) *******************************************************************************/

(0008) void main(void)

(0009) {

(0010)        

(0011)         INT16U ADwtmp16;   //取波形通道采样值

(0012)         INT16U ADetmp16;   //取能量通道采样值

(0013)         INT8Ui,j;

(0014)         INT8U timer0 = 0;

    0713 2400      CLR        R0

    0714 820E      STD        Y+6,R0

(0015)         INT32U tmpc = 0;

    0715 E040      LDI        R20,0

    0716 E050      LDI        R21,0

    0717 E060      LDI        R22,0

    0718 E070      LDI        R23,0

    0719 01FE      MOVW        R30,R28

    071A 8342      STD        Z+2,R20

    071B 8353      STD        Z+3,R21

    071C 8364      STD        Z+4,R22

    071D 8375      STD        Z+5,R23

(0016)         INT8U tmpt = 0;

    071E 24AA      CLR        R10

(0017)        

(0018)        

(0019)         INT8U uarttmp = 0;   //区别采样数据发送类别

    071F 820F      STD        Y+7,R0

paulw 发表于 2007-5-8 11:41:40

iccavr版本6.30C avrstudio版本4.13

经过avrstudio反汇编发现,复位后程序直接跳转到06F1处,为何?0x06F1到0x0711之间为启动代码,其主要功能为初始化硬件和软件堆栈指针,bss 区全部初始化为零,从idata 区拷贝初始化数据到直接寻址数据区data 区,调用main 函数,定义main函数退出点等。

我的理解是启动代码应该是在中断向量表之后的,即0x48处开始,请马老师指点指点。

反汇编代码如下:

+00000000:   940C06F1    JMP   0x000006F1       Jump

+00000002:   FFFF      ???                      Data or unknown opcode

-------

-------

+00000048:   0007      ???                      Data or unknown opcode

+00000049:   800A      LDD   R0,Y+2         Load indirect with displacement

+0000004A:   6032      ORI   R19,0x02         Logical OR with immediate

+0000004B:   18C2      SUB   R12,R2         Subtract without carry

+0000004C:   E03F      LDI   R19,0x0F         Load immediate

+0000004D:   2020      AND   R2,R0            Logical AND

+0000004E:   E03F      LDI   R19,0x0F         Load immediate

+0000004F:   2020      AND   R2,R0            Logical AND

+00000050:   E03F      LDI   R19,0x0F         Load immediate

+00000051:   0000      NOP                      No operation

+00000052:   F8FF      ???                      Data or unknown opcode

+00000053:   0000      NOP                      No operation

+00000054:   0084      ???                      Data or unknown opcode

+00000055:   F067      BRIE    PC+0x0D          Branch if interrupt enabled

+00000056:   1024      CPSE    R2,R4            Compare, skip if equal

+00000057:   1008      CPSE    R0,R8            Compare, skip if equal

+00000058:   D007      RCALL   PC+0x0008      Relative call subroutine

+00000059:   50E4      SUBI    R30,0x04         Subtract immediate

+0000005A:   5024      SUBI    R18,0x04         Subtract immediate

+0000005B:   D027      RCALL   PC+0x0028      Relative call subroutine

+0000005C:   5024      SUBI    R18,0x04         Subtract immediate

+0000005D:   5024      SUBI    R18,0x04         Subtract immediate

+0000005E:   D02F      RCALL   PC+0x0030      Relative call subroutine

+0000005F:   1030      CPSE    R3,R0            Compare, skip if equal

+00000060:   6020      ORI   R18,0x00         Logical OR with immediate

+00000061:   0000      NOP                      No operation

--------------

--------------

+000006F1:   EFCF      SER   R28            Set Register

+000006F2:   E1D0      LDI   R29,0x10         Load immediate

+000006F3:   BFCD      OUT   0x3D,R28         Out to I/O location

+000006F4:   BFDE      OUT   0x3E,R29         Out to I/O location

+000006F5:   51C0      SUBI    R28,0x10         Subtract immediate

+000006F6:   40D0      SBCI    R29,0x00         Subtract immediate with carry

+000006F7:   EA0A      LDI   R16,0xAA         Load immediate

+000006F8:   8308      STD   Y+0,R16          Store indirect with displacement

+000006F9:   2400      CLR   R0               Clear Register

+000006FA:   E4E8      LDI   R30,0x48         Load immediate

+000006FB:   E0F1      LDI   R31,0x01         Load immediate

+000006FC:   E019      LDI   R17,0x09         Load immediate

+000006FD:   37EF      CPI   R30,0x7F         Compare with immediate

+000006FE:   07F1      CPC   R31,R17          Compare with carry

+000006FF:   F011      BREQ    PC+0x03          Branch if equal

+00000700:   9201      ST      Z+,R0            Store indirect and postincrement

+00000701:   CFFB      RJMP    PC-0x0004      Relative jump

+00000702:   8300      STD   Z+0,R16          Store indirect with displacement

+00000703:   E9EA      LDI   R30,0x9A         Load immediate

+00000704:   E0FD      LDI   R31,0x0D         Load immediate

+00000705:   E0A0      LDI   R26,0x00         Load immediate

+00000706:   E0B1      LDI   R27,0x01         Load immediate

+00000707:   E01D      LDI   R17,0x0D         Load immediate

+00000708:   3EE2      CPI   R30,0xE2         Compare with immediate

+00000709:   07F1      CPC   R31,R17          Compare with carry

+0000070A:   F021      BREQ    PC+0x05          Branch if equal

+0000070B:   95C8      LPM                      Load program memory

+0000070C:   9631      ADIW    R30,0x01         Add immediate to word

+0000070D:   920D      ST      X+,R0            Store indirect and postincrement

+0000070E:   CFF9      RJMP    PC-0x0006      Relative jump

+0000070F:   940E0712    CALL    0x00000712       Call subroutine

+00000711:   CFFF      RJMP    PC-0x0000      Relative jump

@00000712: main

---- scr\main.c -----------------------------------------------------------------------------------

8:      void main(void)

+00000712:   9728      SBIW    R28,0x08         Subtract immediate from word

14:               INT8U timer0 = 0;

+00000713:   2400      CLR   R0               Clear Register

+00000714:   820E      STD   Y+6,R0         Store indirect with displacement

15:               INT32U tmpc = 0;

+00000715:   E040      LDI   R20,0x00         Load immediate

--------------

--------------

machao 发表于 2007-5-8 13:15:59

采用任何的高级语言环境,它在编译你的代码时都要加上其本身的系统初始化程序,这些程序包括中断向量的设置、堆栈指针的设置,必要的内存清零,以及系统本身需要使用的寄存器设置等。



    作为程序员本身并没有编写这些必要的初始化代码,但编译系统必须要给你加上的。这样做节省了程序员的时间,也是使用高级语言的优点,但也容易培养出一批“高级傻瓜程序员”。



    再者,系统从0000H开始执行跳转指令,但并没有规定必须跳到堆栈后执行,它是可以跳到任何地方的。ICCAVR先把一些它自己的内部函数、宏操作定位到堆栈后的代码空间中,然后在放置启动代码,最后是你的代码的。

paulw 发表于 2007-5-8 13:45:00

“ICCAVR先把一些它自己的内部函数、宏操作定位到堆栈后的代码空间中”这句话最为点睛,谢谢马老师!!!

也就是说堆栈到启动代码之间的空间跟我所引用的ICCAVR内部函数及宏操作有直接关联,事实我做了几次实验,果真如此。原来我的想法是“0000H---堆栈结束”+“启动代码”+“应用程序”,还有就是原来我认为初始化代码==启动代码。

   这次明白了,嘻嘻!
页: [1]
查看完整版本: 由ICCAVR编译mega128的mp文件,为何从0x06F1执行程序?