One question: would a real CPU have a JL instruction or would that be implemented some other way, like a series of smaller instructions?
One question: would a real CPU have a JL instruction or would that be implemented some other way, like a series of smaller instructions?
CMP RAX, RBX
JL label
would jump if RAX < RBX.Similarly, on ARM:
CMP r1, r2
BLT label /* jump if r1<r2 */
Some processors do have a conditional jump that takes the registers to compare though, such as the PDP-10's bewildering array of skip instructions: CAML A, B
ADDI C, 100 ; This instruction will be skipped if A < B
Finally, it's also fairly common to have branch instructions that compare against 0, such as PDP-10: JUMPL A, label ; jump if A<0
That said, off the top of my head, I don't know of any real processors with something equivalent to the fantasy CPU's JL, which combines a comparison between two registers with a jump to an arbitrary immediate.Depending on the ISA [3][4][5], there can be jumps, branches, and subroutine transfers (or even a subset of those). Some can be based (conditional) on what value is in a primary register (often traditionally called the accumulator), a condition/flag/status register, a memory location, and even well known constants (0, 1, -1). Many ISAs have ways branching to a function/subroutine/procedure that can include adjusting a calling stack or transferring control to an OS kernel. x86 is notable in that you can cause a branch or jump without calling a branch or jump instruction.
[0] https://www.tutorialspoint.com/assembly_programming/assembly...
[1] https://thinkingeek.com/2013/01/19/arm-assembler-raspberry-p...
[2] https://www.ibm.com/developerworks/library/l-powasm3/index.h...
[3] https://en.wikipedia.org/wiki/Instruction_set_architecture
I'm curious what you are referring to here. Are you talking about CMOV? Or INT/SYSCALL/SYSENTER? Or just the ability to trigger a fault handler? Or semantic games like push followed by ret?
In RISC-V's case, you cannot jump to an arbitrary address conditionally at all, you have to use a branch instruction. B-type instructions have only a 12-bit immediate value (technically 13 bits with an implied 0 in the lowest order bit), which means it can only code for jumps up to +- 1024 words away (IIRC, this 13 bit value codes for a jump up to +- 2048 half-words away, but RISC-V instructions are full words, hence 1024... using the 16-bit extensions would change things I think).
RISC-V J-types have a 20 bit jump target addressing relative half-words giving you a range of 2^20 / (2 * 2) = +- 262144 full words. Alternative you could use JALR, which will let you jump to any 32-bit address, but then you would have potentially up to 4 instructions for a conditional jump (blt, luo, ori, jalr).
To my recollection, MIPS is similar but has a larger immediate field for J-types. I'm not familiar enough with other arches to be comment on them.
The way you would code for a conditional jump to a far away target would be to use a conditional branch, which either skips over or runs an unconditional jump. If using JALR as described, you might have something like:
...
blt t1, t2, jump_not_taken
lui t3, 0x1234 # upper 20 bits of jump target
ori t3, 0x456 # lower 12 bits of jump target
jalr t3
jump_not_taken:
...
To answer the question more concisely, something like JL would probably end up being an assembler pseudo-instruction. For example in RISC-V there is no BGE instruction, it compiles to a BLE with the operands swapped. This reduces overhead in the instruction encoding, and is equivalent.AMD64/IA32 are probably different, but I don't know. And of course you could always define a CPU architecture with something like "conditional jump to register value" (JALRLT for example). I don't know if anybody has though.
Source: https://riscv.org/technical/specifications/
Edit: in the time it too me to write this, somebody did the same thing for x86: https://news.ycombinator.com/item?id=24256275