我有一个int
指针和一个char
指针。
我知道那个指针只存储一个内存地址。现在,如果我有一个int
指针,当我请求下一个值时,我的地址会增加4个字节。
现在,当我们请求下一个值时,int
指针必须增加4个字节,char
指针必须增加1个字节,我们在编译器或内存中的何处存储指令?
考虑一个包含两个操作数p + n
的"加号"运算。如果p
的类型是"指向int
的指针",而n
的类型是int
,则编译器生成指令来计算地址,该地址是p
所指向的n
乘以sizeof(int)
字节。如果p
的类型是"指向char
的指针",而n
的类型是int
,则编译器生成指令来计算p
所指向的地址之外的n
乘以sizeof(char)
字节的地址。
类似地,在表达式*p
中,如果p
的类型是"指向int
的指针",编译器将生成一条从内存加载四字节整数的指令。如果p
的类型是"指向char
的指针",编译器会生成一条从内存加载一个单字节整数的指令。
对于下标运算,p[n]
被定义为*((p(+(n((`,因此它是上述两个运算的组合。
(请注意,上述内容适用于孤立表达式的简单编译。总体而言,编译器可能会优化程序,因此生成的程序集可能与上述内容不同,但效果相同。(
增量存储在汇编代码中。你可能会看到eax+4或3[eax]的东西(顺便说一句,这两个不一样(。从本质上讲,汇编代码是在运行时告诉计算机如何增量。
编译器如何知道要执行此操作?这是来自编译器的代码。它创建了所谓的抽象系统树或更有用的图。这些图可以确保规则得到遵守,就像增量一样。
如果你对此感兴趣,可以读一本关于编译器和计算机体系结构的书。
试试吧。
int fun1 ( int *x )
{
unsigned int ra;
int sa;
sa=0;
for(ra=0;ra<100;ra++)
{
sa+=x[ra];
}
return(sa);
}
char fun2 ( char *x )
{
unsigned int ra;
char sa;
sa=0;
for(ra=0;ra<100;ra++)
{
sa+=x[ra];
}
return(sa);
}
char fun3 ( short *x )
{
unsigned int ra;
short sa;
sa=0;
for(ra=0;ra<100;ra++)
{
sa+=x[ra];
}
return(sa);
}
00000000 <fun1>:
0: e3a02000 mov r2, #0
4: e2403004 sub r3, r0, #4
8: e2800f63 add r0, r0, #396 ; 0x18c
c: e5b31004 ldr r1, [r3, #4]!
10: e1530000 cmp r3, r0
14: e0822001 add r2, r2, r1
18: 1afffffb bne c <fun1+0xc>
1c: e1a00002 mov r0, r2
20: e12fff1e bx lr
00000024 <fun2>:
24: e3a03000 mov r3, #0
28: e2402001 sub r2, r0, #1
2c: e2801063 add r1, r0, #99 ; 0x63
30: e5f20001 ldrb r0, [r2, #1]!
34: e0833000 add r3, r3, r0
38: e1520001 cmp r2, r1
3c: e20330ff and r3, r3, #255 ; 0xff
40: 1afffffa bne 30 <fun2+0xc>
44: e1a00003 mov r0, r3
48: e12fff1e bx lr
0000004c <fun3>:
4c: e3a03000 mov r3, #0
50: e2402002 sub r2, r0, #2
54: e280c0c6 add r12, r0, #198 ; 0xc6
58: e1f210b2 ldrh r1, [r2, #2]!
5c: e0813003 add r3, r1, r3
60: e1a00803 lsl r0, r3, #16
64: e1a03000 mov r3, r0
68: e152000c cmp r2, r12
6c: e1a00820 lsr r0, r0, #16
70: e1a03843 asr r3, r3, #16
74: 1afffff7 bne 58 <fun3+0xc>
78: e20000ff and r0, r0, #255 ; 0xff
7c: e12fff1e bx lr
你可以清楚地看到:
c: e5b31004 ldr r1, [r3, #4]!
30: e5f20001 ldrb r0, [r2, #1]!
58: e1f210b2 ldrh r1, [r2, #2]!
您还可以看到半字和字节操作的处理(此体系结构使用32位寄存器(。