アセンブラをリファクタリング中
子守の合間にアセンブラをリファクタリングしていた。ようやくまとまってきた。リファクタリングの過程で x86-64 のアドレッシングに関して更に理解が深まった。
mov とか lea はおおよそ以下の pack-op 手続きでアセンブルできる。
(define (pack-op bits64? opcode mod r64 r/m64 scale index base disp0/8/32 imm8/32) (receive (rex-prefix modrr/m sib) (if scale (compose-reg+sib mod r64 scale index base) (compose-reg mod r64 r/m64)) (values `(,@(if bits64? (list rex-prefix) '()) ,opcode ,modrr/m ,@sib ,@disp0/8/32 ,@imm8/32) #f))) (define (compose-reg mod r64 r/m64) (values (rex-prefix #t (ext-reg? r64) #f (ext-reg? r/m64)) (mod-r-r/m mod r64 r/m64) (cond ;; r/m = #b*100 (rsp, r12) requires sib except mod=#x11 ;; see http://www.mztn.org/lxasm64/amd05.html [(and (not (= mod mod.register)) (memq r/m64 '(#b0100 #b1100))) (let ([r64-index #b100]) ;; #b100 means "none", no index. (list (sib sib.scale1 r64-index r/m64)))] [else '()]))) (define (compose-reg+sib mod r64 scale index base) (values (rex-prefix #t (ext-reg? r64) (ext-reg? index) #f) (mod-r-r/m mod r64 #b100) ;; r/m64 = #b100 is SIB flag. (list (sib scale index base))))