Assembly 如何在这段x86代码中设置零标志?
今天,由于以下x86程序集中idiv指令中的算术异常,我们发生了崩溃Assembly 如何在这段x86代码中设置零标志?,assembly,x86-64,divide-by-zero,Assembly,X86 64,Divide By Zero,今天,由于以下x86程序集中idiv指令中的算术异常,我们发生了崩溃 mov r10d,DWORD PTR [rbp+0x70] xor ecx,ecx mov eax,r15d test r10d,r10d setle cl cdq idiv ecx 以下是gdb中所有寄存器的值: rax 0x64 100 rbx 0xaebc30 11451440 rcx 0x0 0 r
mov r10d,DWORD PTR [rbp+0x70]
xor ecx,ecx
mov eax,r15d
test r10d,r10d
setle cl
cdq
idiv ecx
以下是gdb中所有寄存器的值:
rax 0x64 100
rbx 0xaebc30 11451440
rcx 0x0 0
rdx 0x0 0
rsi 0x1 1
rdi 0xaebc88 11451528
rbp 0x7fa56809b840 0x7fa56809b840
rsp 0x7fa56effc080 0x7fa56effc080
r8 0x12 18
r9 0x100016a0000a72e 72059148816131886
r10 0x1 1
r11 0x0 0
r12 0x9e2bb8 10365880
r13 0x0 0
r14 0xaebc80 11451520
r15 0x64 100
rip 0x495ebb 0x495ebb
eflags 0x246 [ PF ZF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
由于设置了零标志,setle cl
将0写入ecx,从而导致被零除。我不明白的是零标志是如何设置的。r10的值是1,所以据我所知,测试r10d,r10d
应该将其取消设置<代码>干熄焦似乎没有修改它,所以我不确定这里发生了什么
有更多x86经验的人能理解问题所在吗?需要更多信息吗?而这个寄存器转储就在idiv之前(或者在GDB捕获到应该是同一个东西的SIGFPE之后) 你倒过来看:ZF=1表示“等于”条件为真。(因此小于或等于
setle
也是正确的)。所以setle cl
应该给你一个1
当R10=1时,R10D=1<代码>R10D&R10D!=0因此应清除ZF。因此,
r10d
不是,这个寄存器转储是在idiv
之前(或者在GDB捕获到SIGFPE之后,应该是相同的东西)
你倒过来看:ZF=1表示“等于”条件为真。(因此小于或等于setle
也是正确的)。所以setle cl
应该给你一个1
当R10=1时,R10D=1<代码>R10D&R10D!=0因此应清除ZF。因此,
r10d
不是,并且该寄存器转储是在idiv
之前(或者在GDB捕获到应该是同一事物的SIGFPE之后)发生的?是的,R10=1,R10D&R10D!=0,因此应清除ZF。因此,r10d
不是此代码设计为在r10>0时崩溃。因此,它确实做到了这一点也就不足为奇了。我后来发现,我在查看程序集时太激动了,错过了代码中明显的愚蠢错误。希望下次我能记住这一点……这个寄存器转储是在idiv之前(或者在GDB捕获到SIGFPE之后,应该是相同的东西)?是的,R10=1,R10D&R10D!=0,因此应清除ZF。因此,r10d
不是此代码设计为在r10>0时崩溃。因此,它确实做到了这一点也就不足为奇了。我后来发现,我在查看程序集时太激动了,错过了代码中明显的愚蠢错误。希望下次我能记住这个。。。
mov r10d, 1
xor ecx,ecx
mov eax, 0x64
test r10d,r10d
setle cl
cdq
idiv ecx