This is on account of dabbrev--search. In your case, the pattern values are your "a" prefix followed by word/symbol-constituent characters, and reverse is nil.
[...]
;;--------------------------------
;; Look for a distinct expansion, using dabbrev--last-table.
;;--------------------------------
(while (and (not found-string)
(if reverse
(re-search-backward pattern1 nil t)
(re-search-forward pattern1 nil t)))
(goto-char (match-beginning 0))
;; In case we matched in the middle of a word,
;; back up to start of word and verify we still match.
(dabbrev--goto-start-of-abbrev)
(if (not (looking-at pattern1))
nil
;; We have a truly valid match. Find the end.
(re-search-forward pattern2)
(setq found-string (match-string-no-properties 0))
(setq result found-string)
[...]
So it finds a match for a, backs up to the start of the word, still matches a (now a different one), and grabs the word as the completion.