指针类型转换

lzy6204 2008-01-02 10:57:38
C语言代码

stmt level Source
1 int *p1; /*一般指针(3字节)*/
2 int xdata*p1; /*xdata指针(2字节)*/
3 int idata*p1; /*idata指针(1字节)*/
4 int code*p1; /*code指针(2字节)*/

void pconver(void) {
p1=p2; /*xdata指针到一般指针 第7行*/
p1=p3; /*idata指针到一般指针 第8行*/
p1=p4; /*code指针到一般指针 第9行*/

p4=p1; /*一般指针到code指针 第11行*/
p3=p1; /*一般指针到idata指针 第12行*/
p2=p1; /*一般指针到xdata指针 第13行*/
}

汇编结果代码(翻译成汇编代码)如下:

Function pconvert(BEGIN)
;第7行
MOV P1,#01H
MOV P1+01H,P2
MOV P1+02H,P2+01H
;第8行
MOV P1,#00H
MOV P1+01H,#00H
MOV P1+02H,P3
;第9行
MOV R3,#0FFH
MOV R2,P4
MOV R1,p4+01H
MOV p1,R3
MOV p1+01H,R2
MOV p1+02H,R1
;第11行
MOV R6,AR2
MOV R7,AR1
MOV p4,R6
MOV P4+01H,R7
;第12行
MOV R7,AR1
MOV p3,R7
;第13行
MOV R6,AR2
MOV p2,R6
MOV p2+01H,R7
;FUNCTION pconver(END)


问题就在13行的R7并没有指针传入
那么这句话MOV p2+01H,R7怎么可以直接这样写,而不是签名前面加一句话:
MOV R7,AR1
MOV p2+01H,R7

请热心人帮忙解疑,谢谢!
注:以上内容来自《单片机C语言Windows环境编程宝典》一书的268-270页,有删节




...全文
227 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lzy6204 2008-01-23
  • 打赏
  • 举报
回复
谢谢楼上这位兄台,那能告诉我
直接按优化过的代码编写出来的程序
会不会有逻辑上的问题呢

换句话说,编译器优化是否有他一定的规则
手写代码的时候能不能按编译器优化过的代码进行编写?
lbing7 2008-01-22
  • 打赏
  • 举报
回复
终于能回复了

因为编译器各种优化策略不一样,所以,具体一样的代码,在不同的编译器不同的编译选项上

得到的结果是不一样的
所以...

有这些和语议以及最终结果不一样的差异,不足为奇

呵呵
winkyxiao1981 2008-01-22
  • 打赏
  • 举报
回复
up
lbing7 2008-01-22
  • 打赏
  • 举报
回复
LZ你再对比一下我给出的两个对比

还没有足够的理由说明是编译器优化的结果吗?

呵呵
lbing7 2008-01-22
  • 打赏
  • 举报
回复
void pointerCover()
{

int * volatile pointerGeneration; /*一般指针(3字节)*/
int xdata * volatile pointerXdata; /*xdata指针(2字节)*/
int idata * volatile pointerIdata; /*idata指针(1字节)*/
int code * volatile pointerCode; /*code指针(2字节)*/

pointerGeneration = pointerXdata;
pointerGeneration = pointerIdata;
pointerGeneration = pointerCode;

pointerGeneration = 4;

pointerXdata = pointerGeneration;
pointerIdata = pointerGeneration;
pointerCode = pointerGeneration;
}

int main()
{
pointerCover();
}

C:0x0000 02005B LJMP STARTUP1(C:005B)
2: {
3:
4: int * volatile pointerGeneration; /*一般指针(3字节)*/
5: int xdata * volatile pointerXdata; /*xdata指针(2字节)*/
6: int idata * volatile pointerIdata; /*idata指针(1字节)*/
7: int code * volatile pointerCode; /*code指针(2字节)*/
8:
9: pointerGeneration = pointerXdata;
C:0x0003 AE0B MOV R6,0x0B
C:0x0005 AF0C MOV R7,0x0C
C:0x0007 AA06 MOV R2,0x06
C:0x0009 A907 MOV R1,0x07
C:0x000B 750801 MOV 0x08,#0x01
C:0x000E 8A09 MOV 0x09,R2
C:0x0010 890A MOV 0x0A,R1
10: pointerGeneration = pointerIdata;
C:0x0012 A90D MOV R1,0x0D
C:0x0014 750800 MOV 0x08,#0x00
C:0x0017 750900 MOV 0x09,#0x00
C:0x001A 890A MOV 0x0A,R1
11: pointerGeneration = pointerCode;
12:
C:0x001C AE0E MOV R6,0x0E
C:0x001E AF0F MOV R7,0x0F
C:0x0020 AA06 MOV R2,0x06
C:0x0022 A907 MOV R1,0x07
C:0x0024 7508FF MOV 0x08,#0xFF
C:0x0027 8A09 MOV 0x09,R2
C:0x0029 890A MOV 0x0A,R1
13: pointerGeneration = 4;
14:
C:0x002B 750800 MOV 0x08,#0x00
C:0x002E 750900 MOV 0x09,#0x00
C:0x0031 750A04 MOV 0x0A,#0x04
15: pointerXdata = pointerGeneration;
C:0x0034 AB08 MOV R3,0x08
C:0x0036 AA09 MOV R2,0x09
C:0x0038 A90A MOV R1,0x0A
C:0x003A AE02 MOV R6,0x02
C:0x003C AF01 MOV R7,0x01
C:0x003E 8E0B MOV 0x0B,R6
C:0x0040 8F0C MOV 0x0C,R7
16: pointerIdata = pointerGeneration;
C:0x0042 AB08 MOV R3,0x08
C:0x0044 AA09 MOV R2,0x09
C:0x0046 A90A MOV R1,0x0A
C:0x0048 AF01 MOV R7,0x01
C:0x004A 8F0D MOV 0x0D,R7
17: pointerCode = pointerGeneration;
C:0x004C AB08 MOV R3,0x08
C:0x004E AA09 MOV R2,0x09
C:0x0050 A90A MOV R1,0x0A
C:0x0052 AE02 MOV R6,0x02
C:0x0054 AF01 MOV R7,0x01
C:0x0056 8E0E MOV 0x0E,R6
C:0x0058 8F0F MOV 0x0F,R7
18: }
19:
C:0x005A 22 RET
99: MOV R0,#IDATALEN - 1
C:0x005B 787F MOV R0,#0x7F
100: CLR A
C:0x005D E4 CLR A
101: IDATALOOP: MOV @R0,A
C:0x005E F6 MOV @R0,A
102: DJNZ R0,IDATALOOP
C:0x005F D8FD DJNZ R0,IDATALOOP(C:005E)
151: MOV SP,#?STACK-1
152: ; This code is required if you use L51_BANK.A51 with Banking Mode 4
153: ; EXTRN CODE (?B_SWITCH0)
154: ; CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
C:0x0061 75810F MOV SP(0x81),#0x0F
155: LJMP ?C_START
C:0x0064 020067 LJMP main(C:0067)
20: int main()
C:0x0067 020003 LJMP pointerCover(C:0003)
lbing7 2008-01-22
  • 打赏
  • 举报
回复
让LZ看看我的这个KEIL的版本的编译后的情况,看来LZ是不信是优化的结果

好像这个更加猛,呵呵

源码:
void pointerCover()
{

int *pointerGeneration; /*一般指针(3字节)*/
int xdata *pointerXdata; /*xdata指针(2字节)*/
int idata *pointerIdata; /*idata指针(1字节)*/
int code *pointerCode; /*code指针(2字节)*/

pointerGeneration = pointerXdata;
pointerGeneration = pointerIdata;
pointerGeneration = pointerCode;

pointerXdata = pointerGeneration;
pointerIdata = pointerGeneration;
pointerCode = pointerGeneration;
}

int main()
{
pointerCover();
}

生成代码:
C:0x0000 020016 LJMP STARTUP1(C:0016)
2: {
3:
4: int *pointerGeneration; /*一般指针(3字节)*/
5: int xdata *pointerXdata; /*xdata指针(2字节)*/
6: int idata *pointerIdata; /*idata指针(1字节)*/
7: int code *pointerCode; /*code指针(2字节)*/
8:
9: pointerGeneration = pointerXdata;
10: pointerGeneration = pointerIdata;
11: pointerGeneration = pointerCode;
12:
C:0x0003 AA0B MOV R2,0x0B
C:0x0005 A90C MOV R1,0x0C
13: pointerXdata = pointerGeneration;
C:0x0007 AE02 MOV R6,0x02
C:0x0009 AF01 MOV R7,0x01
C:0x000B 8E08 MOV 0x08,R6
C:0x000D 8F09 MOV 0x09,R7
14: pointerIdata = pointerGeneration;
C:0x000F 8F0A MOV 0x0A,R7
15: pointerCode = pointerGeneration;
C:0x0011 8E0B MOV 0x0B,R6
C:0x0013 8F0C MOV 0x0C,R7
16: }
17:
C:0x0015 22 RET
99: MOV R0,#IDATALEN - 1
C:0x0016 787F MOV R0,#0x7F
100: CLR A
C:0x0018 E4 CLR A
101: IDATALOOP: MOV @R0,A
C:0x0019 F6 MOV @R0,A
102: DJNZ R0,IDATALOOP
C:0x001A D8FD DJNZ R0,IDATALOOP(C:0019)
151: MOV SP,#?STACK-1
152: ; This code is required if you use L51_BANK.A51 with Banking Mode 4
153: ; EXTRN CODE (?B_SWITCH0)
154: ; CALL ?B_SWITCH0 ; init bank mechanism to code bank 0
C:0x001C 75810C MOV SP(0x81),#0x0C
155: LJMP ?C_START
C:0x001F 020022 LJMP main(C:0022)
18: int main()
C:0x0022 020003 LJMP pointerCover(C:0003)

不仅去掉了其它的多余的语句,还直接把pointerCover函数内联了
呵呵
lzy6204 2008-01-22
  • 打赏
  • 举报
回复
楼上的,麻烦你仔细看看代码
;第11行
MOV R6,AR2
MOV R7,AR1

=========
第11行也有这么一句话 MOV R7,AR1

那么为什么第11行有了这句话,第12行还要加一句 MOV R7,AR1

既然编译器已经优化,那么第12行也不应该出现那句话

这如何解释,据我所知,每段汇编代码都应该是相互独立的,互不影响的
lbing7 2008-01-02
  • 打赏
  • 举报
回复
也许是编译器优化了...

因为R7的内容没有改变...

lzy6204 2008-01-02
  • 打赏
  • 举报
回复
楼上说的什么意思
shulei521 2008-01-02
  • 打赏
  • 举报
回复
stmt level Source
1 int *p1; /*一般指针(3字节)*/
2 int xdata*p1; /*xdata指针(2字节)*/
3 int idata*p1; /*idata指针(1字节)*/
4 int code*p1; /*code指针(2字节)*/

void pconver(void) {
p1=p2; /*xdata指针到一般指针 第7行*/
p1=p3; /*idata指针到一般指针 第8行*/
p1=p4; /*code指针到一般指针 第9行*/

p4=p1; /*一般指针到code指针 第11行*/
p3=p1; /*一般指针到idata指针 第12行*/
p2=p1; /*一般指针到xdata指针 第13行*/
}

汇编结果代码(翻译成汇编代码)如下:

Function pconvert(BEGIN)
;第7行
MOV P1,#01H
MOV P1+01H,P2
MOV P1+02H,P2+01H
;第8行
MOV P1,#00H
MOV P1+01H,#00H
MOV P1+02H,P3
;第9行
MOV R3,#0FFH
MOV R2,P4
MOV R1,p4+01H
MOV p1,R3
MOV p1+01H,R2
MOV p1+02H,R1
;第11行
MOV R6,AR2
MOV R7,AR1
MOV p4,R6
MOV P4+01H,R7
;第12行
MOV R7,AR1
MOV p3,R7
;第13行
MOV R6,AR2
MOV p2,R6
MOV p2+01H,R7
;FUNCTION pconver(END)

MBWQ 2008-01-02
  • 打赏
  • 举报
回复
;第12行
MOV R7,AR1
已经有了,后面也没改变
好好学习汇编!!!
lzy6204 2008-01-02
  • 打赏
  • 举报
回复
谢谢,还有没有哪位兄弟明白其中的道道

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧