diff --git a/README.adoc b/README.adoc index be31937..00f9ba8 100644 --- a/README.adoc +++ b/README.adoc @@ -12382,6 +12382,31 @@ Bibliography: * link:userland/arch/x86_64/jmp.S[JMP] ** link:userland/arch/x86_64/jmp_indirect.S[JMP indirect] +==== x86 Jcc instructions + +link:userland/arch/x86_64/jcc.S[Jcc] + +Jump if certain conditions of the flags register are met. + +Jcc includes the instructions: + +* JZ, JNZ +** JE, JNE: same as JZ, with two separate manual entries that say almost the same thing, lol: https://stackoverflow.com/questions/14267081/difference-between-je-jne-and-jz-jnz/14267662#14267662 +* JG: greater than, signed +** JA: Above: greater than, unsigned +* JL: less than, signed +** JB below: less than, unsigned +* JC: carry +* JO: overflow +* JP: parity. Why it exists: https://stackoverflow.com/questions/25707130/what-is-the-purpose-of-the-parity-flag-on-a-cpu +* JPE: parity even +* JPO: parity odd + +JG vs JA and JL vs JB: + +* https://stackoverflow.com/questions/20906639/difference-between-ja-and-jg-in-assembly +* https://stackoverflow.com/questions/9617877/assembly-jg-jnle-jl-jnge-after-cmp + === x86 SIMD History: diff --git a/userland/arch/x86_64/jcc.S b/userland/arch/x86_64/jcc.S new file mode 100644 index 0000000..3e645d4 --- /dev/null +++ b/userland/arch/x86_64/jcc.S @@ -0,0 +1,62 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-jcc-instructions */ + +#include + +LKMC_PROLOGUE + /* JZ, JE */ + mov $1, %r12 + cmp $1, %r12 + LKMC_ASSERT(jz) + cmp $2, %r12 + LKMC_ASSERT(jnz) + + /* JA, JB, JG, JL */ + + /* 0x0 == + * + * * 0 in 2's complement signed + * * 0 in 2's complement unsigned + */ + mov $0, %al + + /* 0xFF == + * + * * -1 in 2's complement signed + * * 255 in 2's complement unsigned + */ + mov $0xFF, %bl + + /* Do the operation. */ + cmp %bl, %al + + /* We push and pop flags with PUSHF and POPF because + * our assert function might change them. All comparisons + * are done with the flags of the original cmp operation. + * + * We push twice to keep the stack aligned to 16 bits + * when calling our C asset function. + */ + pushf + pushf + + /* 0 < 255 */ + LKMC_ASSERT(jb) + popf + pushf + + /* ! 0 > 255 */ + LKMC_ASSERT(jna) + popf + pushf + + /* ! 0 < -1 */ + LKMC_ASSERT(jnl) + popf + pushf + + /* 0 > -1 */ + LKMC_ASSERT(jg) + + /* Restore stack. */ + add $16, %rsp +LKMC_EPILOGUE