mirror of
https://github.com/simon987/Much-Assembly-Required.git
synced 2025-04-19 18:46:43 +00:00
Added first draft of instructions up to 0x1D
parent
53571e7e73
commit
804af72104
@ -63,3 +63,534 @@ Operand value:
|
||||
| Register | `00001`-`01000` |
|
||||
| [Register] | `01001`-`10000` |
|
||||
| Register + Immediate value at IP+1 | `10001`-`11000` |
|
||||
|
||||
|
||||
***
|
||||
> NOTE: Work In Progress
|
||||
# Instruction Set
|
||||
## Introduction
|
||||
This is an effort to specify the specific MAR Assembly Instruction Set and its behaviour. The instruction set is a subset of the 8086 instruction set. A more detailed specification if the 8086 Instruction Set can be found [here](http://www.ousob.com/ng/iapx86/ng2e5.php). Note that the MAR Instruction Set can differ from the 8086 Instruction Set.
|
||||
|
||||
This manual tries to describe how to use the instructions and show any side effects they might have.
|
||||
|
||||
Each instruction has a `Mnemonic` or syntax. This is the way the instruction is written in human readable format. This exists of the instruction name and its operands (if any).
|
||||
|
||||
```s
|
||||
MOV A, 0x20
|
||||
```
|
||||
|
||||
This human readable format is parsed by the assembler which will output the actual binary opcodes and operands. More about the encoding can be read [below](#Encoding).
|
||||
|
||||
## Instructions
|
||||
### BRK
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `BRK` | `0x00` | | `-` | `-` | `-` | `-` | `1` |
|
||||
|
||||
#### Description
|
||||
`BRK` sets the break flag. This will halt execution until the next game 'tick', where it will be cleared and execution resumes from the start of the `.text` label.
|
||||
|
||||
### MOV
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `MOV destination, source` | `0x01` | `destination` : `reg` / `mem` | `-` | `-` | `-` | `-` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`MOV` transfers (copies) a word from the source operand to the destination operand.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = source
|
||||
```
|
||||
|
||||
### ADD
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `ADD destination, source` | `0x02` | `destination` : `reg` / `mem` | `X` | `X` | `X` | `X` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`ADD` replaces the destination operand with the sum of the source and destination operands. It sets the carry flag if there is an overflow.
|
||||
|
||||
### Pseudo code
|
||||
```py
|
||||
destination = destination + source
|
||||
```
|
||||
|
||||
### SUB
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `SUB destination, source` | `0x03` | `destination` : `reg` / `mem` | `X` | `X` | `X` | `X` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`SUB` subtracts the source operand from the destination operand and stores the result in destination.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> When an immediate byte value is subtracted from a word operand, the immediate value is first sign-extended to the size of the destination operand.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination - source
|
||||
```
|
||||
|
||||
### AND
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `AND destination, source` | `0x04` | `destination` : `reg` / `mem` | `0` | `X` | `X` | `0` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`AND` performs a bit-by-bit logical AND operation on its operands
|
||||
and stores the result in destination. `AND` sets each bit of the
|
||||
result to one if both of the corresponding bits of the operands
|
||||
are one.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination & source
|
||||
```
|
||||
|
||||
### OR
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `OR destination, source` | `0x05` | `destination` : `reg` / `mem` | `0` | `X` | `X` | `0` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`OR` performs a bit-by-bit logical inclusive OR operation on its
|
||||
operands and returns the result to destination. `OR` sets each bit
|
||||
of the result to one if either or both of the corresponding bits
|
||||
of the operands are one.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination | source
|
||||
```
|
||||
|
||||
### SHL (Shift Logical Left)
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `SHL destination, count` | `0x06` | `destination` : `reg` / `mem` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`SHL` shifts the bits of the destination operand upward (toward the
|
||||
most significant bit) by the number of bit positions specified in
|
||||
the second operand (count). As bits are transferred out of the
|
||||
left (high-order) end of the destination, zero bits are shifted
|
||||
into the right (low-order) end.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> The carry flag (CF) is set equal
|
||||
to the last bit shifted out of the left end.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination << count
|
||||
```
|
||||
|
||||
### SHR (Shift Logical Right)
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `SHR destination, count` | `0x07` | `destination` : `reg` / `mem` | `X` | `-` | `-` | `X` | `-` |
|
||||
| | | `count` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
SHR shifts the bits of the destination operand downward (toward
|
||||
the least significant bit) by the number of bit positions
|
||||
specified in the second operand (count). As bits are transferred
|
||||
out of the right (low-order) end of the destination, zero bits are
|
||||
shifted into the left (high-order) end.
|
||||
|
||||
> ? TODO: is this implemented?
|
||||
> The carry flag (CF) is set
|
||||
equal to the last bit shifted out of the right end.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = destination >> count
|
||||
```
|
||||
|
||||
### HWI (Hardware Interrupt)
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `HWI source` | `0x09` | `source` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`HWI` triggers an [Hardware Interrupt](https://github.com/simon987/Much-Assembly-Required/wiki/Hardware). `source` should be the address of the harware device. This is differnt from the RAM memory addresses. See the documentation of the hardware devices to see what an `HWI` does for each device.
|
||||
|
||||
### JMP
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JMP target` | `0x0A` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JMP` performs an unconditional jump to the target memory address and will resume execution there.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
IP = target
|
||||
```
|
||||
|
||||
### TEST
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `TEST destination, source` | `0x0B` | `destination` : `reg` / `mem` | `0` | `X` | `X` | `0` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`TEST` performs a logical AND operation on its two operands and
|
||||
updates the flags. None of the operands are changed.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination & source # flags will be set
|
||||
```
|
||||
|
||||
### CMP
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `CMP destination, source` | `0x0C` | `destination` : `reg` / `mem` | `X` | `X` | `X` | `X` | `-` |
|
||||
| | | `source` : `reg` / `mem` / `imm` |
|
||||
|
||||
#### Description
|
||||
`CMP` compares two numbers by subtracting the source from the
|
||||
destination and updates the flags. None of the operands are
|
||||
changed.
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination - source # flags will be set
|
||||
```
|
||||
|
||||
### JNZ
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JNZ target` | `0x0D` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JNZ` performs a jump if the zero flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if ZERO_FLAG == 0:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JZ
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JZ target` | `0x0E` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JZ` performs a jump if the the zero flag **IS** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if ZERO_FLAG == 1:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JG
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JG target` | `0x0F` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JG` performs a jump if the sign flag **IS EQUAL** to the overflow flag **AND** the zero flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG == OVERFLOW_FLAG and ZERO_FLAG == 0:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JGE
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JGE target` | `0x10` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JGE` performs a jump if the sign flag **IS EQUAL** to the overflow flag
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG == OVERFLOW_FLAG:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JL
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JL target` | `0x11` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JL` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG != OVERFLOW_FLAG:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JLE
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JLE target` | `0x12` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JLE` performs a jump if the sign flag **IS NOT EQUAL** to the overflow flag **OR** the zero flag **IS** set
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG != OVERFLOW_FLAG or ZERO_FLAG == 1:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### PUSH
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `PUSH source` | `0x13` | `source` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`PUSH` decrements the stack pointer by one and then copies `source` to the address the stack pointer is pointing to.
|
||||
> The stack grows downwards from 0xFFFF -> 0x0000
|
||||
> So decrementing will 'grow' the stack
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
SP = SP - 1
|
||||
memory[SP] = source
|
||||
```
|
||||
|
||||
### POP
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `POP destintation` | `0x14` | `destination` : `reg` / `mem` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`POP` copies the value of the memory address specified in the stack pointer to the `destination` and increments the stack pointer.
|
||||
> The stack grows downwards from 0xFFFF -> 0x0000
|
||||
> So incrementing will 'shrink' the stack
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
destination = memory[SP]
|
||||
SP = SP + 1
|
||||
```
|
||||
|
||||
### CALL
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `CALL target` | `0x15` | `target` : `reg` / `mem` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`CALL` pushes the current instruction pointer on to the stack and then performs a jump to the `target` address
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
SP = SP - 1
|
||||
memory[SP] = IP
|
||||
IP = target
|
||||
```
|
||||
|
||||
### RET
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `RET [amount]` | `0x16` | `amount` : `imm` / `None` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`RET` jumps to the address stored at the stack pointer and then increments (pops) that address of the stack.
|
||||
When `amount` is given increment the stack pointer the number of times given in amount.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
IP = memory[SP]
|
||||
if amount == None:
|
||||
amount = 0
|
||||
SP = SP + 1 + amount
|
||||
```
|
||||
|
||||
### MUL
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `MUL source` | `0x17` | `source` : `mem` / `reg` / `imm` | `X` | `-` | `-` | `X` | `-` |
|
||||
|
||||
#### Description
|
||||
`MUL` performs unsigned multiplication with `A` and `source` and stores the result into `Y:A`.
|
||||
|
||||
The result of the multiplication is stored into `Y:A` where the higher order bits are stored in `Y` and the lower order bits are stored in `A`
|
||||
|
||||
The carry and overflow flags are set to 1 if the high-order of the result is bigger than 0; otherwise, CF and OF are reset to 0.
|
||||
|
||||
> This is a somewhat complicated instruction
|
||||
> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/MulInstruction.java) if needed
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
|
||||
# result is a 32-bit integer
|
||||
result = A * source
|
||||
# get the 16 most significant bits of result
|
||||
higher_order_word = (result & 0xff00)
|
||||
|
||||
if higher_order_word != 0:
|
||||
OVERFLOW_FLAG = 1
|
||||
CARRY_FLAG = 1
|
||||
Y = higher_order_word
|
||||
else:
|
||||
OVERFLOW_FLAG = 0
|
||||
CARRY_FLAG = 0
|
||||
A = (result & 0x00ff)
|
||||
|
||||
# result is stored in Y:A
|
||||
# you can check if you need Y by check the flags
|
||||
```
|
||||
|
||||
### DIV
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `DIV source` | `0x18` | `source` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `X` |
|
||||
|
||||
#### Description
|
||||
`DIV` performs unsigned division on `A` with `source` as divisor and stores the result into `A` and the remainder in `Y`.
|
||||
|
||||
Note that a division by 0 will set the (undocumented) error flag and the break flag. This will halt execution.
|
||||
|
||||
> This is a somewhat complicated instruction
|
||||
> See the [source](https://github.com/simon987/Much-Assembly-Required/blob/master/Server/source/main/java/net/simon987/server/assembly/instruction/DivInstruction.java) if needed
|
||||
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
|
||||
if source == 0:
|
||||
ERROR_FLAG = 1
|
||||
BREAK_FLAG = 1
|
||||
|
||||
# temp is a 32-bit integer
|
||||
temp = (Y << 16) | A
|
||||
|
||||
A = temp / source # result is floored
|
||||
Y = temp % source
|
||||
|
||||
```
|
||||
|
||||
### NEG
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `NEG destintation` | `0x19` | `destination` : `mem` / `reg` | `X` | `X` | `X` | `X` | `-` |
|
||||
|
||||
#### Description
|
||||
`NEG` subtracts the destination operand from 0 and returns the result in the destination. This effectively produces the two's complement of the operand.
|
||||
|
||||
If the operand is zero, the carry flag is cleared; in all other cases, the carry flag is set.
|
||||
|
||||
Attempting to negate a word containing -32,768 causes no change to the operand and sets the Overflow Flag.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if destination == 0:
|
||||
CARRY_FLAG = 0
|
||||
ZERO_FLAG = 1
|
||||
else:
|
||||
CARRY_FLAG = 1
|
||||
|
||||
if destination == -32768:
|
||||
OVERFLOW_FLAG = 1
|
||||
else
|
||||
destination = 0 - destination # or destination = destination + (-dest)
|
||||
```
|
||||
|
||||
### JS
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JS target` | `0x1A` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JS` jumps to the target if the sign flag **IS** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG == 1:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### JNS
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `JNS target` | `0x1B` | `target` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`JNS` jumps to the target if the sign flag **IS NOT** set.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if SIGN_FLAG == 0:
|
||||
IP = target
|
||||
```
|
||||
|
||||
### HWQ
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `HWQ source` | `0x1C` | `source` : `mem` / `reg` / `imm` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`HWQ` queries the hardware id of the hardware at the hardware address specified by `source`
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
if hardware_memory[source] != None:
|
||||
B = get_hardware_id(hardware_memory[source]) # not sure how to (pseudo) code this
|
||||
else:
|
||||
B = 0
|
||||
```
|
||||
|
||||
### NOT
|
||||
#### Details
|
||||
| mnemonic | opcode | operands | carry | zero | sign | overflow | break |
|
||||
| -------- | ------ | -------- | ----- | ---- | ---- | -------- | ----- |
|
||||
| `NOT destintation` | `0x1D` | `source` : `mem` / `reg` | `-` | `-` | `-` | `-` | `-` |
|
||||
|
||||
#### Description
|
||||
`NOT` inverts each bit in its operand, i.e. forms the one's complement.
|
||||
|
||||
#### Pseudo code
|
||||
```py
|
||||
dest = ~dest
|
||||
```
|
||||
|
||||
## Encoding
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user