Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
---|---|---|---|---|---|
10 /r ADC r/m8, r8 | mr | Valid | Valid | Valid | Add r/m8, the carry flag, and r8 into r/m8. |
REX 10 /r ADC r/m8*, r8* | mr | N/E | N/E | Valid | Add r/m8, the carry flag, and r8 into r/m8. This uses the alterate gpr8 encoding. |
11 /r ADC r/m16, r16 | mr | Valid | Valid | Valid | Add r/m16, the carry flag, and r16 into r/m16. |
11 /r ADC r/m32, r32 | mr | Valid | Valid | Valid | Add r/m32, the carry flag, and r32 into r/m32. |
REX.W 11 /r ADC r/m64, r64 | mr | N/E | N/E | Valid | Add r/m64, the carry flag, and r64 into r/m64. |
12 /r ADC r8, r/m8 | rm | Valid | Valid | Valid | Add r8, the carry flag, and r/m8 into r8. |
REX 12 /r ADC r8*, r/m8* | rm | N/E | N/E | Valid | Add r8, the carry flag, and r/m8 into r8. This uses the alterate gpr8 encoding. |
13 /r ADC r16, r/m16 | rm | Valid | Valid | Valid | Add r16, the carry flag, and r/m16 into r16. |
13 /r ADC r32, r/m32 | rm | Valid | Valid | Valid | Add r32, the carry flag, and r/m32 into r32. |
REX.W 13 /r ADC r64, r/m64 | rm | N/E | N/E | Valid | Add r64, the carry flag, and r/m64 into r64. |
14 ib ADC AL, imm8 | ai | Valid | Valid | Valid | Add AL , the carry flag, and imm8 into AL . |
15 iw ADC AX, imm16 | ai | Valid | Valid | Valid | Add AX , the carry flag, and imm16 into AX . |
15 id ADC EAX, imm32 | ai | Valid | Valid | Valid | Add EAX , the carry flag, and imm32 into EAX . |
REX.W 15 id ADC RAX, imm32 | ai | N/E | N/E | Valid | Add RAX , the carry flag, and imm32 (sign extended to 64 bits) into RAX . |
80 /2 ib ADC r/m8, imm8 | mi | Valid | Valid | Valid | Add r/m8, the carry flag, and imm8 into r/m8. |
REX 80 /2 ib ADC r/m8*, imm8* | mi | Valid | Valid | Valid | Add r/m8, the carry flag, and imm8 into r/m8. This uses the alterate gpr8 encoding. |
81 /2 iw ADC r/m16, imm16 | mi | Valid | Valid | Valid | Add r/m16, the carry flag, and imm16 into r/m16. |
81 /2 id ADC r/m32, imm32 | mi | Valid | Valid | Valid | Add r/m32, the carry flag, and imm32 into r/m32. |
REX.W 81 /2 id ADC r/m64, imm32 | mi | N/E | N/E | Valid | Add r/m64, the carry flag, and imm32 (sign extended to 64 bits) into r/m64. |
82 /2 ib ADC r/m8, imm8 | mi | Valid | Valid | Invalid | Add r/m8, the carry flag, and imm8 (sign extended to 8 bits) into r/m8. Undocumented. |
83 /2 ib ADC r/m16, imm8 | mi | Valid | Valid | Valid | Add r/m16, the carry flag, and imm8 (sign extended to 16 bits) into r/m16. |
83 /2 ib ADC r/m32, imm8 | mi | Valid | Valid | Valid | Add r/m32, the carry flag, and imm8 (sign extended to 32 bits) into r/m32. |
REX.W 83 /2 ib ADC r/m64, imm8 | mi | N/E | N/E | Valid | Add r/m64, the carry flag, and imm8 (sign extended to 64 bits) into r/m64. |
Encoding
Encoding | Operand 1 | Operand 2 |
---|---|---|
mr | ModRM.r/m[rw] | ModRM.reg[r] |
rm | ModRM.reg[rw] | ModRM.r/m[r] |
ai | AL/AX/EAX/RAX | imm8/16/32 |
mi | ModRM.r/m[rw] | imm8/16/32 |
Description
The ADC
instruction adds the source operand, the destination operand, and the carry flag. The result is stored in the destination operand.
This instruction is designed for use in multiword additions such as in arbitrary precision arithmetic.
This instruction can be used with the LOCK
prefix to allow atomic exectution.
Operation
// `src` is sign extended to the width of `dest`
public void ADC(ref U8 dest, U8 src)
{
dest += src + CF;
}
public void ADC(ref U16 dest, U16 src)
{
dest += src + CF;
}
public void ADC(ref U32 dest, U32 src)
{
dest += src + CF;
}
public void ADC(ref U64 dest, U64 src)
{
dest += src + CF;
}
Flags Affected
CF
(carry flag)- Set according to the result.
PF
(parity flag)- Set according to the result.
AF
(auxiliary flag)- Set according to the result.
ZF
(zero flag)- Set according to the result.
SF
(sign flag)- Set according to the result.
OF
(overflow flag)- Set according to the result.
Intrinsics
uint8_t _addcarry_u8(uint8_t c_in, uint8_t src1, uint8_t src2, uint8_t *sum_out)
uint8_t _addcarry_u16(uint8_t c_in, uint16_t src1, uint16_t src2, uint16_t *sum_out)
uint8_t _addcarry_u32(uint8_t c_in, uint32_t src1, uint32_t src2, uint32_t *sum_out)
uint8_t _addcarry_u64(uint8_t c_in, uint64_t src1, uint64_t src2, uint64_t *sum_out)
Exceptions
Exception | Mode | Cause of Exception | |||
---|---|---|---|---|---|
Real Mode | Virtual 8086 | Protected and Compatibility | Long Mode | ||
#UD | X | X | X | X | If the LOCK prefix is used, but the destination is not a memory operand. |
#SS(0) | X | X | X | X | If a memory operand using the SS segment has an effective address that is outside the SS segment's limit. |
X | If a memory operand using the SS segment is in non-canonical form. | ||||
#GP(0) | X | X | X | X | If a memory operand (using a segment other than SS ) has an effective address that is outside the segment's limit. |
X | X | If the destination is located in a non-writable segment. | |||
X | X | If a memory operand uses a segment containing a NULL selector. | |||
X | If a memory operand (using a segment other than SS ) is in non-canonical form. | ||||
#PF(fc) | X | X | X | If a page fault occurs. | |
#AC(0) | X | X | X | If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made. |