Skip to content

BUG: error in translating the "sbb" instruction #1196

Open
@zyt755

Description

@zyt755

There is an error in lifting the x86 instruction "sbb" to IRs while calculating the AF flag.

Since %32 and 15 perform unsigned greater than calculations, %33 will only become true when %32 is greater than 15 or less than 0. Therefore, Retdec will only set AF to 1 when the least significant 4 bits of eax is 0xf. However, in a real CPU, if CF is 1 after this instruction is executed, AF will be set to 1. Otherwise, AF will be 0.

The original instruction is sbb %eax, %eax
The following is how IRs of "sbb" calculate the AF flag, where an error exists.

store volatile i64 4195574, i64* @_asm_program_counter
%19 = load i64, i64* @rax
%20 = trunc i64 %19 to i32   ; %eax
%21 = load i64, i64* @rax
%22 = trunc i64 %21 to i32   ; %eax
%23 = load i1, i1* @cf
%24 = zext i1 %23 to i32      ; @cf 32bits
%25 = add i32 %22, %24     ; %eax + @cf
%27 = and i32 %20, 15        ; (%eax)_low 4bits
%28 = and i32 %25, 15        ; (%eax + @cf)_low 4bits
%29 = sub i32 %27, %28     ; (%eax)_low4bits - (%eax + @cf)_low4bits
%30 = load i1, i1* @cf
%31 = zext i1 %30 to i32      ; @cf 32bits
%32 = add i32 %29, %31     
%33 = icmp ugt i32 %32, 15
store i1 %33, i1* @az

The following are the completed IRs of "sbb".

store volatile i64 4195574, i64* @_asm_program_counter
%19 = load i64, i64* @rax
%20 = trunc i64 %19 to i32
%21 = load i64, i64* @rax
%22 = trunc i64 %21 to i32
%23 = load i1, i1* @cf
%24 = zext i1 %23 to i32
%25 = add i32 %22, %24
%26 = sub i32 %20, %25
%27 = and i32 %20, 15
%28 = and i32 %25, 15
%29 = sub i32 %27, %28
%30 = load i1, i1* @cf
%31 = zext i1 %30 to i32
%32 = add i32 %29, %31
%33 = icmp ugt i32 %32, 15
%34 = load i1, i1* @cf
%35 = zext i1 %34 to i32
%36 = sub i32 %26, %35
%37 = icmp ult i32 %20, %36
%38 = icmp ult i32 %25, -1
%39 = or i1 %37, %38
%40 = icmp ult i32 %20, %25
%41 = select i1 %34, i1 %39, i1 %40
%42 = load i1, i1* @cf
%43 = zext i1 %42 to i32
%44 = sub i32 %26, %43
%45 = xor i32 %20, %25
%46 = xor i32 %20, %44
%47 = and i32 %45, %46
%48 = icmp slt i32 %47, 0
store i1 %33, i1* @az
store i1 %41, i1* @cf
store i1 %48, i1* @of
%49 = icmp eq i32 %26, 0
store i1 %49, i1* @zf
%50 = icmp slt i32 %26, 0
store i1 %50, i1* @sf
%51 = trunc i32 %26 to i8
%52 = call i8 @llvm.ctpop.i8(i8 %51)
%53 = and i8 %52, 1
%54 = icmp eq i8 %53, 0
store i1 %54, i1* @pf
%55 = zext i32 %26 to i64
store i64 %55, i64* @rax

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions