Jason Knight
2 min readAug 9, 2022

--

Back when I was actually applying for full time jobs -- a good 14 years ago now -- I used to love to trip up interviewers who would ask for this with the caveat "in your favorite programming language"

And giving them 16 bit x86 assembly.

isPalindrome:; ACCEPTS
; DS:SI == address of string, length delimited (pascal style)
; CORRUPTS
; AH == should be zero
; RETURNS
; AL == first character mismatch on failure, zero on success
PUSH DI ; preserve used registers
PUSH SI
MOV DI, SI ; copy string pointer to DI
XOR AH, AH ; clear upper 8 bits of AX
LODSB ; load string length into AL, inc pointer
ADD DI, AX ; DI is now pointing at last character
.loop:
CMP SI, DI ; compare start and end pointers
JLE .success ; start >= end exit as success.
LODSB ; load character from start
CMP AL, [DI] ; compare to character at end
JNE .exit ; not equal, exit as failure
DEC DI ; decrease end pointer
JMP .loop ; and try again
.success:
XOR AL, AL ; Zero AL on success
.exit:
POP SI ; restore used registers
POP DI
RETF ; and return

The thing is I tend to do all my coding and problem solving with the mindset of an assembly langauge programmer. This stems from my first "real" programming language being hand assembling RCA 1802 machine language and entering it one bit at a time on tolggle switches on a COSMAC Elf.

Assembly -- especially within the limits of early 8 and 16 bit hardware -- gives a different perspective on solving problems. That perspective makes me a bit horrified by the answers you presented because they waste memory creating extra copies of the string, create stack thrashing by calling a whole slew of functions inside the function, and are in no way efficient from a raw performance or logic standpoint.

Which is why for example, I’d code that in JavaScript as:

const isPalindrome = (word) => {
for (
let first = 0, last = word.length - 1;
first < last;
first++, last--
) if (word[first] !== word[last]) return false;
return true;
}

Which is basically more or less what the machine language one is doing. Put a pointer at the start, a pointer at the end, compare length where if it’s equal it’s true, compare the character at each if it’s not equal abort as false, the inc/dec the pointers to lather-rinse-repeat. If we get all the way to the pointers passing each-other or being equal, it’s a palindrome.

No extra creating copies of the string, no extra function call overhead.

And I know that code will piss off a lot of todays pedantic idiots who lose their minds over concepts like early exit, a practice once held up as the pinnacle of GOOD programming!

--

--

Jason Knight
Jason Knight

Written by Jason Knight

Accessibility and Efficiency Consultant, Web Developer, Musician, and just general pain in the arse

No responses yet