Il linguaggio C++ non ha alcun concetto di contrassegno carry, pertanto la creazione di un wrapper di funzione intrinseca attorno allo ADC
instruction è netta. Tuttavia, Intel lo ha fatto comunque: unsigned char _addcarry_u32 (unsigned char c_in, unsigned a, unsigned b, unsigned * out);
. L'ultima volta che ho controllato, gcc ha fatto un pessimo lavoro con questo (salvando il risultato di carry in un registro intero, invece di lasciarlo in CF), ma si spera che il compilatore di Intel funzioni meglio.
Vedere anche il tag wiki x86 per la documentazione di assemblaggio.
Il compilatore utilizzerà ADC per voi quando si aggiungono numeri interi più ampi di un singolo registro, ad es. aggiungendo int64_t
in codice a 32 bit o __int128_t
in codice a 64 bit.
#include <stdint.h>
#ifdef __x86_64__
__int128_t add128(__int128_t a, __int128_t b) { return a+b; }
#endif
# clang 3.8 -O3 for x86-64, SystemV ABI.
# __int128_t args passed in 2 regs each, and returned in rdx:rax
add rdi, rdx
adc rsi, rcx
mov rax, rdi
mov rdx, rsi
ret
asm uscita da Godbolt compiler explorer. clang's -fverbose-asm
non è molto vebose, ma gcc 5.3/6.1 spreca due istruzioni mov
quindi è meno leggibile.
fonte
2016-06-10 01:15:19
quale processore? – Chubsdad
@Chubsdad: ho fatto del mio meglio per aggiungere alcune informazioni. Spero sia abbastanza –
Quale compilatore? Per accedere al flag carry, devi incorporare il codice assembler nel tuo codice C++. Il modo in cui lo fai dipende dal compilatore che stai utilizzando. – TonyK