;name: checkparity.asm ; ;build: nasm "-felf64" checkparity.asm -l checkparity.lst -o checkparity.o ; ld -s -melf_x86_64 -o checkparity checkparity.o ; ;description: "In x86 processors, the parity flag reflects the parity only of the least significant ; byte of the result, and is set if the number of set bits of ones is even." ; source: http://en.wikipedia.org/wiki/Parity_flag ; Therefore this example algorithm to determine the parity of a 63 bit dataword in RAX. Bit ; 63 (remember we count the bits starting at zero) will be used as the parity bit of the ; dataword. ;remark: ;As an extra option you can choose to calculate parity even or parity odd paritybit. ;Just keep in mind that parity odd is less in use, therefor parity even in the example. ;Even so, parity checks aren't common on 63 bits, the chance having more than one ;erroneous bit increases with the number of bits in a dataword. BITS 64 [list -] %include "unistd.inc" %include "sys/termios.inc" [list +] %define PARITY_EVEN 1 %define PARITY_ODD 0 %define PARITY_METHOD PARITY_EVEN ; define to PARITY_ODD if you like the other parity check method ;the databits on which we will test ; bitnumbers ; ---------------------------------------------------------------- ; 66 6 5 4 3 2 1 ; 43 0 0 0 0 0 0 0 %define DATABITS 1110000000000000000000000000000000000000000000000000000000000000b ;bit 64 is the paritybit that comes with the dataword, remember we don't calculate, we check. ;We expect the message "parity not correct" since we check on even parity and there is an odd ;number of 1 bits section .data message: db "The parity bit is " .placeholder db 0,0,0,0 ; to store "NOT " if the check result in not ok %if PARITY_METHOD = PARITY_EVEN db "1.", 10 %else db "0.", 10 %endif .length: equ $-message section .text global _start _start: ;we cannot check the parity of the entire 64 bit word on a Intel x86 ;therefor this routine mov al, PARITY_METHOD ;set the parity method in AL mov cl, 8 ;check 8 bits at the time mov rdx, DATABITS ;databits to test in RDX rcl rdx, 1 ;move the parity bit via the CFlag adc ah, 0 ;into AH and back clc ;clear carry bit rcr rdx, 1 ;into his original place nextGroup: test rdx, rdx ;test parity of DL jp isParityEven ;if parity even don't touch AL xor al, 1 ;if parity odd invert AL isParityEven: shr rdx, 8 ;next group of 8 bits or cl, cl ;compare CL with zero, if zero then we are done loopnz nextGroup ;process next group of 8 bits cmp ah, al ;compare both the received paritybit (AH) with the calculated ;paritybit (AL) je write ;write the message mov ebx, "not " ;if paritybits aren't the same then modify the message mov dword [message.placeholder], ebx ;by putting "NOT " into the placeholder write: syscall write, stdout, message, message.length syscall exit, 0