|
楼主 |
发表于 2007-7-25 00:43:46
|
显示全部楼层
这两天使用WinAVR-20070525 + avrstudio4.13.528 + UE,觉得还可以,期间碰到一个问题,就是选择了另外一个源文件,Build and RUN 无法出现程序空间使用情况及永远出现原先的源文件的编译结果,后来怀疑是文件夹为中文名及文件目录太深的原因,改过后就好了。找来一个芯艺的例程,看看编译出来的ASM 文件如何,还不错,
#include <avr/io.h>
volatile register uint8_t controller_flag0 asm("r22");
#define f_high_voltage 0
#define f_high_voltage_sc 0b00000001
#define f_super_current 1
#define f_super_current_sc 0b00000010
#define f_automatic_phase 2
#define f_automatic_phase_sc 0b00000100
#define f_calibrate_limit_current 3
#define f_calibrate_limit_current_sc 0b00001000
#define f_normal_brake 4
#define f_normal_brake_sc 0b00010000
#define f_limit_current 5
#define f_limit_current_sc 0b00100000
#define f_low_voltage 6
#define f_low_voltage_sc 0b01000000
#define f_motor_halt_buf 7
#define f_motor_halt_buf_sc 0b10000000
int main(void)
{
DDRC=0X0F;
PORTC=0X0F;
controller_flag0 = PORTC;
if ((controller_flag0 & f_high_voltage_sc) == 0) //这个位判断及位操作的做法还请熟悉的朋友详细解释一下,我自己也不太确定这样写是否合适,只是不停的改,看ASM 的代码正确了就这样写了
controller_flag0 |= (1<<f_high_voltage);
}
编译结果
Build started 25.7.2007 at 00:24:54
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex winavr_study.elf winavr_study.eep || exit 0
c:\WinAVR-20070525\bin\avr-objcopy.exe: there are no sections to be copied!
AVR Memory Usage
----------------
Device: atmega48
Program: 126 bytes (3.1% Full)
(.text + .data + .bootloader)
Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)
Build succeeded with 0 Warnings...
lss 文件,我比较喜欢看这个文件,容易看出WINAVR 怎么处理成ASM 的
winavr_study.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000007e 00000000 00000000 00000054 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .stab 00000378 00000000 00000000 000000d4 2**2
CONTENTS, READONLY, DEBUGGING
2 .stabstr 00000071 00000000 00000000 0000044c 2**0
CONTENTS, READONLY, DEBUGGING
3 .debug_aranges 00000020 00000000 00000000 000004bd 2**0
CONTENTS, READONLY, DEBUGGING
4 .debug_pubnames 00000030 00000000 00000000 000004dd 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_info 00000094 00000000 00000000 0000050d 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_abbrev 00000066 00000000 00000000 000005a1 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_line 000000cb 00000000 00000000 00000607 2**0
CONTENTS, READONLY, DEBUGGING
8 .debug_frame 00000020 00000000 00000000 000006d4 2**2
CONTENTS, READONLY, DEBUGGING
9 .debug_str 0000009c 00000000 00000000 000006f4 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:
00000000 <__vectors>:
0: 19 c0 rjmp .+50 ; 0x34 <__ctors_end>
2: 33 c0 rjmp .+102 ; 0x6a <__bad_interrupt>
4: 32 c0 rjmp .+100 ; 0x6a <__bad_interrupt>
6: 31 c0 rjmp .+98 ; 0x6a <__bad_interrupt>
8: 30 c0 rjmp .+96 ; 0x6a <__bad_interrupt>
a: 2f c0 rjmp .+94 ; 0x6a <__bad_interrupt>
c: 2e c0 rjmp .+92 ; 0x6a <__bad_interrupt>
e: 2d c0 rjmp .+90 ; 0x6a <__bad_interrupt>
10: 2c c0 rjmp .+88 ; 0x6a <__bad_interrupt>
12: 2b c0 rjmp .+86 ; 0x6a <__bad_interrupt>
14: 2a c0 rjmp .+84 ; 0x6a <__bad_interrupt>
16: 29 c0 rjmp .+82 ; 0x6a <__bad_interrupt>
18: 28 c0 rjmp .+80 ; 0x6a <__bad_interrupt>
1a: 27 c0 rjmp .+78 ; 0x6a <__bad_interrupt>
1c: 26 c0 rjmp .+76 ; 0x6a <__bad_interrupt>
1e: 25 c0 rjmp .+74 ; 0x6a <__bad_interrupt>
20: 24 c0 rjmp .+72 ; 0x6a <__bad_interrupt>
22: 23 c0 rjmp .+70 ; 0x6a <__bad_interrupt>
24: 22 c0 rjmp .+68 ; 0x6a <__bad_interrupt>
26: 21 c0 rjmp .+66 ; 0x6a <__bad_interrupt>
28: 20 c0 rjmp .+64 ; 0x6a <__bad_interrupt>
2a: 1f c0 rjmp .+62 ; 0x6a <__bad_interrupt>
2c: 1e c0 rjmp .+60 ; 0x6a <__bad_interrupt>
2e: 1d c0 rjmp .+58 ; 0x6a <__bad_interrupt>
30: 1c c0 rjmp .+56 ; 0x6a <__bad_interrupt>
32: 1b c0 rjmp .+54 ; 0x6a <__bad_interrupt>
00000034 <__ctors_end>:
34: 11 24 eor r1, r1
36: 1f be out 0x3f, r1 ; 63 //SREG = 0
38: cf ef ldi r28, 0xFF ; 255
3a: d2 e0 ldi r29, 0x02 ; 2
3c: de bf out 0x3e, r29 ; 62
3e: cd bf out 0x3d, r28 ; 61 //SP = RAMEND = 0X2FF
00000040 <__do_copy_data>:
40: 11 e0 ldi r17, 0x01 ; 1 //这一段不是太清楚,熟悉的朋友解释一下可以用来干嘛,为何只比较0x100组数据
42: a0 e0 ldi r26, 0x00 ; 0
44: b1 e0 ldi r27, 0x01 ; 1
46: ee e7 ldi r30, 0x7E ; 126
48: f0 e0 ldi r31, 0x00 ; 0
4a: 02 c0 rjmp .+4 ; 0x50 <.do_copy_data_start>
0000004c <.do_copy_data_loop>:
4c: 05 90 lpm r0, Z+
4e: 0d 92 st X+, r0
00000050 <.do_copy_data_start>:
50: a0 30 cpi r26, 0x00 ; 0
52: b1 07 cpc r27, r17
54: d9 f7 brne .-10 ; 0x4c <.do_copy_data_loop>
00000056 <__do_clear_bss>:
56: 11 e0 ldi r17, 0x01 ; 1 //这一段不是太清楚,熟悉的朋友解释一下可以用来干嘛,为何只比较0x100组数据
58: a0 e0 ldi r26, 0x00 ; 0
5a: b1 e0 ldi r27, 0x01 ; 1
5c: 01 c0 rjmp .+2 ; 0x60 <.do_clear_bss_start>
0000005e <.do_clear_bss_loop>:
5e: 1d 92 st X+, r1
00000060 <.do_clear_bss_start>:
60: a0 30 cpi r26, 0x00 ; 0
62: b1 07 cpc r27, r17
64: e1 f7 brne .-8 ; 0x5e <.do_clear_bss_loop>
66: 02 d0 rcall .+4 ; 0x6c <main>
68: 09 c0 rjmp .+18 ; 0x7c <_exit>
0000006a <__bad_interrupt>:
6a: ca cf rjmp .-108 ; 0x0 <__vectors>
0000006c <main>:
#define f_motor_halt_buf 7
#define f_motor_halt_buf_sc 0b10000000
int main(void)
{
6c: 8f e0 ldi r24, 0x0F ; 15
6e: 87 b9 out 0x07, r24 ; 7
DDRC=0X0F;
PORTC=0X0F;
70: 88 b9 out 0x08, r24 ; 8
controller_flag0 = PORTC;
72: 88 b1 in r24, 0x08 ; 8
74: 68 2f mov r22, r24
if ((controller_flag0 & f_high_voltage_sc) == 0)
76: 60 ff sbrs r22, 0
controller_flag0 |= (1<<f_high_voltage);
78: 61 60 ori r22, 0x01 ; 1
7a: 08 95 ret
0000007c <_exit>:
7c: ff cf rjmp .-2 ; 0x7c <_exit>
可以看出程序也没有多出什么来,就是那2段__do_copy_data,__do_clear_bss。而__vectors,__ctors_end 用ASM 写也是要做的,另外就是main 变成函数了,成了
66: 02 d0 rcall .+4 ; 0x6c <main>
这样看来,解决了位判断及寄存器全局变量的使用问题,就可以用WINAVR 来改我的ASM 程序了,不用再反复检查及验证ASM 编写的乘除法计算程序了 |
|