0000009d <test8>:
9d: 55 push %ebp
9e: 89 e5 mov %esp,%ebp
a0: 83 ec 20 sub $0x20,%esp
a3: c7 45 ef 01 00 01 00 movl $0x10001,-0x11(%ebp)
aa: c7 45 f3 01 00 01 00 movl $0x10001,-0xd(%ebp)
b1: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
b8: eb 28 jmp e2 <test8+0x45>
ba: c7 45 f8 00 00 0a 00 movl $0xa0000,-0x8(%ebp)
c1: 8d 55 ef lea -0x11(%ebp),%edx
c4: 8b 45 fc mov -0x4(%ebp),%eax
c7: 01 d0 add %edx,%eax
c9: 8a 00 mov (%eax),%al
cb: 88 45 f7 mov %al,-0x9(%ebp)
ce: 80 7d f7 00 cmpb $0x0,-0x9(%ebp)
d2: 74 0b je df <test8+0x42>
d4: 8b 55 fc mov -0x4(%ebp),%edx
d7: 8b 45 f8 mov -0x8(%ebp),%eax
da: 01 d0 add %edx,%eax
dc: c6 00 01 movb $0x1,(%eax)
df: ff 45 fc incl -0x4(%ebp)
e2: 83 7d fc 07 cmpl $0x7,-0x4(%ebp)
e6: 7e d2 jle ba <test8+0x1d>
e8: 90 nop
e9: 90 nop
ea: c9 leave
eb: c3 ret
0000003a <test16>:
3a: 55 push %ebp
3b: 89 e5 mov %esp,%ebp
3d: 57 push %edi
3e: 56 push %esi
3f: 53 push %ebx
40: 83 ec 20 sub $0x20,%esp
43: 8d 45 db lea -0x25(%ebp),%eax
46: bb 00 00 00 00 mov $0x0,%ebx
4b: ba 0f 00 00 00 mov $0xf,%edx
50: 89 c7 mov %eax,%edi
52: 89 de mov %ebx,%esi
54: 89 d1 mov %edx,%ecx
56: f3 a4 rep movsb %ds:(%esi),%es:(%edi)
58: c6 45 ea 00 movb $0x0,-0x16(%ebp)
5c: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp)
63: eb 28 jmp 8d <test16+0x53>
65: c7 45 ec 00 00 0a 00 movl $0xa0000,-0x14(%ebp)
6c: 8d 55 db lea -0x25(%ebp),%edx
6f: 8b 45 f0 mov -0x10(%ebp),%eax
72: 01 d0 add %edx,%eax
74: 8a 00 mov (%eax),%al
76: 88 45 eb mov %al,-0x15(%ebp)
79: 80 7d eb 00 cmpb $0x0,-0x15(%ebp)
7d: 74 0b je 8a <test16+0x50>
7f: 8b 55 f0 mov -0x10(%ebp),%edx
82: 8b 45 ec mov -0x14(%ebp),%eax
85: 01 d0 add %edx,%eax
87: c6 00 01 movb $0x1,(%eax)
8a: ff 45 f0 incl -0x10(%ebp)
8d: 83 7d f0 0f cmpl $0xf,-0x10(%ebp)
91: 7e d2 jle 65 <test16+0x2b>
93: 90 nop
94: 90 nop
95: 83 c4 20 add $0x20,%esp
98: 5b pop %ebx
99: 5e pop %esi
9a: 5f pop %edi
9b: 5d pop %ebp
9c: c3 ret
以上汇编均是C编译生成,代码如下,我全部都一样除了数组长度,但我不知道为什么test16会执行异常
void test16(){
char test[16] = {1,0,1,0,1,0,1,0,0,0,0,0,0,1};
int i;
char *p,d;
for (i = 0; i <16; i++) {
p = displayaddr;
d = test[i];
if(d){p[i] = 1;}
// if(d){drawpoint(1,i,1);}
}
}
void test8(){
char test[8] = {1,0,1,0,1,0,1,0};
int i;
char *p,d;
for (i = 0; i <8; i++) {
p = displayaddr;
d = test[i];
if(d){p[i] = 1;}
}
}
这两个函数的主要区别在于操作的变量类型不同。test8操作的是字节类型(1个字节),而test16操作的是双字类型(2个字节)。
具体来说,test8使用了一个字节的指针(eax)来访问字节,然后将它们复制到一个字节的缓冲区(-0x9(%ebp)和-0x15(%ebp))。而test16使用了一个双字的指针(eax)来访问双字,然后将它们复制到一个字节的缓冲区(-0x10(%ebp)和-0x15(%ebp))。这导致test16试图将两个字节复制到一次只能复制一个字节的缓冲区,导致越界问题。
因此,test8能够执行成功,而test16会执行失败。