(如果 BYTE PTR [ebp+0x8] 得到一个大于 1 字节的参数会怎样?比如 0xcdc485c1

(What happens if the BYTE PTR [ebp+0x8] get a parameter greater than 1 byte? like 0xcdc485c1

所以...我有这个 test.S 文件,他从中得到这个参数:asm3(0xcdc485c1,0xd6bd5e88,0xe4c1548d)

代码:

```asm3:
      <+0>:   push   ebp
      <+1>:   mov    ebp,esp
      <+3>:   xor    eax,eax
      <+5>:   mov    ah,BYTE PTR [ebp+0x8]
      <+8>:   shl    ax,0x10
      <+12>:  sub    al,BYTE PTR [ebp+0xe]
      <+15>:  add    ah,BYTE PTR [ebp+0xc]
      <+18>:  xor    ax,WORD PTR [ebp+0x10]
      <+22>:  nop
      <+23>:  pop    ebp
      <+24>:  ret```

我想知道 0xcdc485c1(ebp+0x8) 会发生什么,因为它有超过 1 个字节,对吗?它只会得到有效字节吗?或者它将被完整存储,如果是这样,为什么? 如果您也知道,这个 "ebp+0xe" 在哪里,它不是参数还是?

在函数的<+3>处,堆栈看起来是这样的:

               0  1  2  3   byte offsets
     + 0x10 | 8d 54 c1 e4 |
     + 0x0c | 88 5e bd d6 |
     + 0x08 | c1 85 c4 cd |
     + 0x04 | return      |
 ebp + 0x00 | prev. ebp   |

其中堆栈上有五个 DWORD(32 位值),每个都采用通常的小端顺序。

无论出于何种原因,后面的代码仅从堆栈中选取几个字节和一个 WORD(16 位)——因此它使用了三个 DWORD 参数的一部分。

一切都是字节;字节加载指令不关心它是如何存储的或它是什么"means",只关心当前内存中的内容。


FWIW:shl ax, 0x10 是一种将 ax 设置为零的冗长/混淆方式。 x86 shifts& 31 掩盖它们的计数,即使操作数大小小于 32 位,所以窄移位可以移出所有位,不像 shl eax, 0x20 什么都不做。