请问下面这两段masm汇编代码为什么test8能执行成功,test16执行失败?

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;}
    }

}
阅读 1.4k
1 个回答

这两个函数的主要区别在于操作的变量类型不同。test8操作的是字节类型(1个字节),而test16操作的是双字类型(2个字节)。
具体来说,test8使用了一个字节的指针(eax)来访问字节,然后将它们复制到一个字节的缓冲区(-0x9(%ebp)和-0x15(%ebp))。而test16使用了一个双字的指针(eax)来访问双字,然后将它们复制到一个字节的缓冲区(-0x10(%ebp)和-0x15(%ebp))。这导致test16试图将两个字节复制到一次只能复制一个字节的缓冲区,导致越界问题。
因此,test8能够执行成功,而test16会执行失败。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏