diff --git a/README.adoc b/README.adoc index d55d16f..785286e 100644 --- a/README.adoc +++ b/README.adoc @@ -12364,6 +12364,7 @@ Bibliography: ** link:userland/arch/x86_64/div_overflow.S[DIV overflow] ** link:userland/arch/x86_64/div_zero.S[DIV zero] ** link:userland/arch/x86_64/idiv.S[IDIV] +* link:userland/arch/x86_64/cmp.S[CMP] === x86 SIMD diff --git a/userland/arch/x86_64/add.S b/userland/arch/x86_64/add.S index 31193b9..9e08abf 100644 --- a/userland/arch/x86_64/add.S +++ b/userland/arch/x86_64/add.S @@ -42,4 +42,18 @@ LKMC_PROLOGUE */ addq memory_immediate, memory_register #endif + + /* ADD and many other instructions automatically update the status flags + * which controls branches. + */ + + /* Equals 0. */ + mov $1, %rax + add $-1, %rax + LKMC_ASSERT(je) + + /* Not equals 0. */ + mov $2, %rax + add $-1, %rax + LKMC_ASSERT(jne) LKMC_EPILOGUE diff --git a/userland/arch/x86_64/cmp.S b/userland/arch/x86_64/cmp.S new file mode 100644 index 0000000..8cf1b8b --- /dev/null +++ b/userland/arch/x86_64/cmp.S @@ -0,0 +1,21 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#userland-assembly + * + * Compare two numbers and set the flags register. + * + * `cmp X, Y` does `X - Y` and ignores the exact result, but sets + * all flags that would be set on the subtraction, just like SUB does. + */ + +#include + +LKMC_PROLOGUE + /* 2 == 2 */ + mov $2, %rax + cmp $2, %rax + LKMC_ASSERT(je) + + /* 2 > 1 */ + mov $2, %rax + cmp $1, %rax + LKMC_ASSERT(ja) +LKMC_EPILOGUE