// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause package asm import ( "encoding/hex" "strings" "testing" "sourcedock.dev/petrbalvin/gasm-sdk/parser" ) // TestRenderedTextEncodes pins the encoder against the disassembler's // renderings: every line here is a text the toolchain's own decoder prints // for bytes its assembler produced (the disasm package's parity fixtures), // so assembling the printed text must reproduce those bytes. Each row was // read back through the toolchain's decoder; the hex is the fixture's. func TestRenderedTextEncodes(t *testing.T) { for _, tt := range []struct { text string want string }{ // The segment-absolute rendering lowers to the FS-prefixed disp32 // absolute, exactly what the 0(FS) spelling encodes. {"MOVQ FS:0, DX", "64488b142500000000"}, } { src := "TEXT \u00b7k(SB), NOSPLIT, $0\n\t" + tt.text + "\n\tRET\n" f, errs := parser.Parse("k.s", src) if len(errs) > 0 { t.Errorf("%s: parse: %v", tt.text, errs[0]) continue } img, err := AssembleFile(f) if err != nil { t.Errorf("%s: assemble: %v", tt.text, err) continue } fn := img.Funcs[0] code := img.Code[fn.Offset : fn.Offset+fn.Size] // The no-fallthrough rule appends the RET; the pinned instruction is // the prefix. got := hex.EncodeToString(code) if !strings.HasPrefix(got, tt.want) { t.Errorf("%s: bytes %s, want prefix %s", tt.text, got, tt.want) } } }