The assembler syntax is rather confusing.
* The opcode names are unneccessariy complicate. For example, instead of using "MOV" for all transfers, there are lots of commands; depending on whether the operands are 8bit or 16bit, registers or immeditiats, immediates, internal or external memory locations, etc.
* Conditionals are pretty unconventional: Unlike as on other CPUs, there are no opcodes like "jump if equal", instead there are opcodes like "compare and if equal then skip next opcode".<br>The next opcode becomes conditionally executed, aside from conditional jumps, this can be also used with other opcodes, so one can program conditional MOV, OR, AND, CALL, etc.<br>Altogether it's pretty cool - once when one is familar with it. The "if-then-skip" requires some reverse thinking since humans would tendencially prefer "if-then-execute".<br>Aside from comparisions there are some other opcodes that set the skip flag, some rotate commands, and decrement commands (where the skip condition is N=-1, not N=0) (to implement a decrement without skip one must put a NOP behind it).<br>There are two other conditional effects: Some opcodes like "LXI HL,imm16" cause any following "LXI HL,imm16" opcode(s) to be skipped; when used after a compare opcode, this can produce a IF-THEN-ELSE effect; it can be also useful when "in-jumping" into a function. Finally, RETS performs are RET and sets the skip-flag (so the next opcode, at the return address/after the CALL opcode, will be skipped)