取模,align_up 函数汇编代码 x86

Modulo, align_up function assembly code x86

我有以下生成的汇编代码,但由于某种原因不断崩溃。

  0000000040001AF0: 48 8D 44 24 30     lea         rax,[rsp+30h]
  0000000040001AF5: 48 89 08           mov         qword ptr [rax],rcx
  0000000040001AF8: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
  0000000040001AFD: 48 89 11           mov         qword ptr [rcx],rdx
  0000000040001B00: 48 8D 54 24 40     lea         rdx,[rsp+40h]
  0000000040001B05: 48 8B 28           mov         rbp,qword ptr [rax]
  0000000040001B08: 48 8B 31           mov         rsi,qword ptr [rcx]
  0000000040001B0B: 48 89 E8           mov         rax,rbp
  0000000040001B0E: 48 31 D2           xor         rdx,rdx
  0000000040001B11: 48 F7 F6           div         rax,rsi
  0000000040001B14: 48 89 D5           mov         rbp,rdx
  0000000040001B17: 48 8D 44 24 40     lea         rax,[rsp+40h]
  0000000040001B1C: 48 89 28           mov         qword ptr [rax],rbp
  0000000040001B1F: 48 8D 54 24 58     lea         rdx,[rsp+58h]
  0000000040001B24: 48 8B 28           mov         rbp,qword ptr [rax]
  0000000040001B27: 48 31 F6           xor         rsi,rsi
  0000000040001B2A: 48 63 F6           movsxd      rsi,esi
  0000000040001B2D: 48 39 F5           cmp         rbp,rsi
  0000000040001B30: BD 00 00 00 00     mov         ebp,0
  0000000040001B35: 0F 94 C5           sete        ch
  0000000040001B38: 48 83 FD 01        cmp         rbp,1
  0000000040001B3C: 0F 84 26 00 00 00  je          0000000040001B68
  0000000040001B42: 48 8D 6C 24 30     lea         rbp,[rsp+30h]
  0000000040001B47: 48 8B 6D 00        mov         rbp,qword ptr [rbp]
  0000000040001B4B: 48 8B 09           mov         rcx,qword ptr [rcx]
  0000000040001B4E: 48 8B 00           mov         rax,qword ptr [rax]
  0000000040001B51: 48 29 C1           sub         rcx,rax
  0000000040001B54: 48 01 CD           add         rbp,rcx
  0000000040001B57: 48 89 2A           mov         qword ptr [rdx],rbp
  0000000040001B5A: 66 0F 1F 44 00 00  nop         word ptr [rax+rax]

  0000000040001B60: 48 8B 12           mov         rdx,qword ptr [rdx]
  0000000040001B63: 48 89 D0           mov         rax,rdx
  0000000040001B66: C3                 ret
  0000000040001B67: 90                 nop

  0000000040001B68: 48 8D 44 24 30     lea         rax,[rsp+30h]
  0000000040001B6D: 48 8B 00           mov         rax,qword ptr [rax]
  0000000040001B70: 48 89 02           mov         qword ptr [rdx],rax
  0000000040001B73: E9 E8 FF FF FF     jmp         0000000040001B60

这是由程序根据以下伪代码函数生成的。

align_up(uint64 value, uint64 alignment) : uint64 {
    uint64 val = value
    uint64 algn = alignment
    // align to the next alignment boundary, if unaligned
    uint64 tmp = val % algn
    return (tmp == 0 ? val : val + (algn - tmp))
}

值和对齐分别在 rcxrdx 中。

任何关于为什么此代码可能会崩溃的想法都将不胜感激。

我知道上面的代码是有问题的代码,因为我可以用下面的代码替换它并且程序按预期执行。

  0000000040001AF0: 48 8D 44 24 30     lea         rax,[rsp+30h]
  0000000040001AF5: 48 89 08           mov         qword ptr [rax],rcx
  0000000040001AF8: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
  0000000040001AFD: 48 89 11           mov         qword ptr [rcx],rdx
  0000000040001B00: 48 8D 54 24 40     lea         rdx,[rsp+40h]
  0000000040001B05: 48 8B 28           mov         rbp,qword ptr [rax]
  0000000040001B08: 48 8B 31           mov         rsi,qword ptr [rcx]
  0000000040001B0B: 48 89 E8           mov         rax,rbp
  0000000040001B0E: 48 31 D2           xor         rdx,rdx
  0000000040001B11: 48 F7 F6           div         rax,rsi
  0000000040001B14: 48 89 D5           mov         rbp,rdx
  0000000040001B17: 48 8D 44 24 40     lea         rax,[rsp+40h]
  0000000040001B1C: 48 89 28           mov         qword ptr [rax],rbp
  0000000040001B1F: 48 8B 10           mov         rdx,qword ptr [rax]
  0000000040001B22: 48 31 ED           xor         rbp,rbp
  0000000040001B25: 48 63 ED           movsxd      rbp,ebp
  0000000040001B28: 48 39 EA           cmp         rdx,rbp
  0000000040001B2B: BA 00 00 00 00     mov         edx,0
  0000000040001B30: 0F 94 C2           sete        dl
  0000000040001B33: 48 83 FA 01        cmp         rdx,1
  0000000040001B37: 0F 84 1B 00 00 00  je          0000000040001B58
  0000000040001B3D: 48 8D 54 24 30     lea         rdx,[rsp+30h]
  0000000040001B42: 48 8B 12           mov         rdx,qword ptr [rdx]
  0000000040001B45: 48 8B 09           mov         rcx,qword ptr [rcx]
  0000000040001B48: 48 8B 00           mov         rax,qword ptr [rax]
  0000000040001B4B: 48 29 C1           sub         rcx,rax
  0000000040001B4E: 48 01 CA           add         rdx,rcx
  0000000040001B51: 48 89 D0           mov         rax,rdx
  0000000040001B54: C3                 ret
  0000000040001B55: 0F 1F 00           nop         dword ptr [rax]

  0000000040001B58: 48 8D 44 24 30     lea         rax,[rsp+30h]
  0000000040001B5D: 48 8B 00           mov         rax,qword ptr [rax]
  0000000040001B60: C3                 ret
  0000000040001B61: 0F 1F 80 00 00 00  nop         dword ptr [rax+0000000000000000h]
                    00

这让我觉得这可能与负跳有关???

  //....
  0000000040001B2D: 48 39 F5           cmp         rbp,rsi
  0000000040001B30: BD 00 00 00 00     mov         ebp,0
  0000000040001B35: 0F 94 C5           sete        ch
  0000000040001B38: 48 83 FD 01        cmp         rbp,1
  //....
  0000000040001B4B: 48 8B 09           mov         rcx,qword ptr [rcx]
  //....

正如 Peter Cordes 所说,“sete ch 在陷入 mov rcx,qword ptr [rcx] 之前”似乎是个问题。这就是问题所在,代码在尝试从 rcx 加载值之前设置了 rcx 的高位字节(第二个字节)。