AS31(1)
πΈ AS31 β an Intel 8031/8051 assembler π
okay bestie, welcome to AS31(1), General Commands Manual edition β this is the assembler that takes your little 8031/8051 assembly and turns it into actual bytes. let's get into it π«Ά
β¨ NAME β¨
as31 β An Intel 8031/8051 assembler
π SYNOPSIS π
as31 [-h] [-l] [-s] [-v] [-Aarg] [-Ffmt] [-Ofile] infile.asm
π DESCRIPTION π
So here's the vibe: as31 assembles infile.asm into one of several different output formats. The output lands in a file called infile.obj. and yes, the .asm extension is required β like, non-negotiable, the assembler will simply not play with you otherwise π
β OPTIONS β
Big rule first, no cap: the options must appear before the input file name. Both options are optional (iconic behavior honestly). And the text of each flag has to appear on the same argument as the flag. For example, -Fod is a valid argument, but -F od is not. spacing matters bestie, she's picky π
-hβ makes the assembler print out a verbose message describing its options. That message goes to standard error. so it's help, but make it stderr, iykyk.-lβ tells the assembler to also generate a listing file. The listing gets placed ininfile.lst, where infile is the file being assembled. This option may appear anywhere beforeinfile.asm, and it must occur isolated on the command line (no roomies, she's an only child).
The listing file shows the assembler generated code in hex, and up to 60 characters are retained from the source file. sixty. that's the number. respect it β¨
-sβ makes the assembler write output to standard output. screen time, babes π₯οΈ-vβ makes the assembler print a version number to standard output. cute little flex π-Aargβ specifies a format specific string which is passed to the format generator. Both thetdrformat and the srecord formats use this option. (two formats, one flag, we love a versatile queen π)-Fformatβ specifies the output format that is to be used.
Currently the only options available for this are:
hexβ this format is the Intel HEX format which is expected by a number of EPROM programmers and the PAULMON debugger. For use with some programmers, the output file's extension may have to be changed to.HEXto be recognized by the programmer. No-Aoption is used. This format should be the default if no-Foption is used. the main character of formats, honestly π§tdrβ this format generates an ASCII file of hex digits formatted in such a way, so that they can be read by tdr's debugger. An argument can be specified (see the-Aoption) which will pass a format specific string to the format generator. In this case, the argument string represents an offset to add to the location counter. This offset is specified in decimal and defaults to64*1024(0x10000). To specify an offset of100, you would need-Ftdr -A100when invoking the assembler.
watch the default here β it is not zero. it's 64*1024. tdr said "go big" π
byteβ this format is simply an address and a byte on each line, in ASCII. No-Aoption is used. minimalism, she ate πodβ this format is similar to the output fromod(1). The format consists of an address followed by sixteen hexadecimal bytes, followed by the equivalent ASCII. No-Aoption is used. sixteen bytes. very aligned. very demure πsrec2,srec3,srec4β the srecord generator is capable of generating output with any one of 2, 3, or 4 byte addresses. The-Aoption can be used to set the base address offset, and the default here is0x0000(unliketdrβ yes, the two formats disagree about defaults, and that's just how it is π).
NOTE: This assembler allows for the output formats to be expanded to include many different output formats. so the list you're seeing? it can grow. the devs left room for more girlies π±
-Ofileβ tells the assembler to write the output to a file. your bytes, your chosen destination π
β¨ ASSEMBLER INSTRUCTIONS β¨
okay so bestie, this assembler fully speaks standard 8031/8051 instruction formats, no cap. Below is the whole list of instructions plus their addressing modes, and every entry shows how many bytes it takes and how many cycles it eats. π
ACALL addr11β 2 bytes, 24 cyclesADD A, #data8β 2 bytes, 12 cyclesADD A, @Riβ 1 bytes, 12 cyclesADD A, Rnβ 1 bytes, 12 cyclesADD A, directβ 2 bytes, 12 cyclesADDC A, #data8β 2 bytes, 12 cyclesADDC A, @Riβ 1 bytes, 12 cyclesADDC A, Rnβ 1 bytes, 12 cyclesADDC A, directβ 2 bytes, 12 cyclesAJMP addr11β 2 bytes, 24 cyclesANL A, #data8β 2 bytes, 12 cyclesANL A, @Riβ 1 bytes, 12 cyclesANL A, Rnβ 1 bytes, 12 cyclesANL A, directβ 2 bytes, 12 cyclesANL C, /bitβ 2 bytes, 24 cyclesANL C, !bitβ 2 bytes, 24 cyclesANL C, bitβ 2 bytes, 24 cyclesANL direct, #data8β 3 bytes, 24 cyclesANL direct, Aβ 2 bytes, 12 cyclesCJNE @Ri, #data8, relβ 3 bytes, 24 cyclesCJNE A, #data8, relβ 3 bytes, 24 cyclesCJNE A, direct, relβ 3 bytes, 24 cyclesCJNE Rn, #data8, relβ 3 bytes, 24 cyclesCLR Aβ 1 bytes, 12 cyclesCLR Cβ 1 bytes, 12 cyclesCLR bitβ 2 bytes, 12 cyclesCPL Aβ 1 bytes, 12 cyclesCPL Cβ 1 bytes, 12 cyclesCPL bitβ 2 bytes, 12 cyclesDA Aβ 1 bytes, 12 cyclesDEC @Riβ 1 bytes, 12 cyclesDEC Aβ 1 bytes, 12 cyclesDEC DPTRβ 1 bytes, 12 cyclesDEC Rnβ 1 bytes, 12 cyclesDEC directβ 2 bytes, 12 cyclesDIV ABβ 1 bytes, 48 cyclesDJNZ Rn, relβ 2 bytes, 24 cyclesDJNZ direct, relβ 3 bytes, 24 cyclesINC @Riβ 1 bytes, 12 cyclesINC Aβ 1 bytes, 12 cyclesINC DPTRβ 1 bytes, 24 cyclesINC Rnβ 1 bytes, 12 cyclesINC directβ 2 bytes, 12 cyclesJB bit, relβ 3 bytes, 24 cyclesJBC bit, relβ 3 bytes, 24 cyclesJC relativeβ 2 bytes, 24 cyclesJMP @A + DPTRβ 1 bytes, 24 cyclesJMP @DPTR + Aβ 1 bytes, 24 cyclesJNB bit, relβ 3 bytes, 24 cyclesJNC relativeβ 2 bytes, 24 cyclesJNZ relativeβ 2 bytes, 24 cyclesJZ relativeβ 2 bytes, 24 cyclesLCALL addr16β 3 bytes, 24 cyclesLJMP addr16β 3 bytes, 24 cyclesMOV @Ri, #data8β 2 bytes, 12 cyclesMOV @Ri, Aβ 1 bytes, 12 cyclesMOV @Ri, directβ 2 bytes, 24 cyclesMOV A, #data8β 2 bytes, 12 cyclesMOV A, @Riβ 1 bytes, 12 cyclesMOV A, Rnβ 1 bytes, 12 cyclesMOV A, directβ 2 bytes, 12 cyclesMOV C, bitβ 2 bytes, 12 cyclesMOV DPTR, #data16β 3 bytes, 24 cyclesMOV Rn, #data8β 2 bytes, 12 cyclesMOV Rn, Aβ 1 bytes, 12 cyclesMOV Rn, directβ 2 bytes, 24 cyclesMOV bit, Cβ 2 bytes, 24 cyclesMOV direct, #data8β 3 bytes, 24 cyclesMOV direct, @Riβ 2 bytes, 24 cyclesMOV direct, Aβ 2 bytes, 12 cyclesMOV direct, Rnβ 2 bytes, 24 cyclesMOV direct, directβ 3 bytes, 24 cyclesMOVC A, @A + DPTRβ 1 bytes, 24 cyclesMOVC A, @A + PCβ 1 bytes, 24 cyclesMOVC A, @DPTR + Aβ 1 bytes, 24 cyclesMOVC A, @PC + Aβ 1 bytes, 24 cyclesMOVX @DPTR, Aβ 1 bytes, 12 cyclesMOVX @Ri, Aβ 1 bytes, 24 cyclesMOVX A, @DPTRβ 1 bytes, 24 cyclesMOVX A, @Riβ 1 bytes, 24 cyclesMUL ABβ 1 bytes, 48 cyclesNOPβ 1 bytes, 12 cyclesORL A, #data8β 2 bytes, 12 cyclesORL A, @Riβ 1 bytes, 12 cyclesORL A, Rnβ 1 bytes, 12 cyclesORL A, directβ 2 bytes, 12 cyclesORL C, /bitβ 2 bytes, 24 cyclesORL C, !bitβ 2 bytes, 24 cyclesORL C, bitβ 2 bytes, 24 cyclesORL direct, #data8β 3 bytes, 24 cyclesORL direct, Aβ 2 bytes, 12 cyclesPOP directβ 2 bytes, 24 cyclesPUSH directβ 2 bytes, 24 cyclesRETβ 1 bytes, 24 cyclesRETIβ 1 bytes, 24 cyclesRL Aβ 1 bytes, 12 cyclesRLC Aβ 1 bytes, 12 cyclesRR Aβ 1 bytes, 12 cyclesRRC Aβ 1 bytes, 12 cyclesSETB Aβ 1 bytes, 12 cyclesSETB bitβ 2 bytes, 12 cyclesSJMP relativeβ 2 bytes, 24 cyclesSUBB A, #data8β 2 bytes, 12 cyclesSUBB A, @Riβ 1 bytes, 12 cyclesSUBB A, Rnβ 1 bytes, 12 cyclesSUBB A, directβ 2 bytes, 12 cyclesSWAP Aβ 1 bytes, 12 cyclesXCH A, #data8β 2 bytes, 12 cyclesXCH A, @Riβ 1 bytes, 12 cyclesXCH A, Rnβ 1 bytes, 12 cyclesXCH A, directβ 2 bytes, 12 cyclesXCHD A, #data8β 2 bytes, 12 cyclesXCHD A, @Riβ 1 bytes, 12 cyclesXCHD A, Rnβ 1 bytes, 12 cyclesXCHD A, directβ 2 bytes, 12 cyclesXRL A, #data8β 2 bytes, 12 cyclesXRL A, @Riβ 1 bytes, 12 cyclesXRL A, Rnβ 1 bytes, 12 cyclesXRL A, directβ 2 bytes, 12 cyclesXRL direct, #data8β 3 bytes, 12 cyclesXRL direct, Aβ 2 bytes, 12 cycles
π ASSEMBLER DIRECTIVES π
bestie, as31 also ships with these assembler directives. they're like the little spells you sprinkle into your source, iykyk. β¨
.ORG expr
okay so this one tells the assembler to start assembling at the address specified by the expression expr. iconic, right?
β οΈ girlies beware: an error occurs if the assembler starts assembling over an address space that has previously been assembled into. so don't be messy with your addresses, fr fr. π
.EQU symbol, expr
sets symbol to the value of expr. easy peasy. π
but lowkey important: the value for expr must be known during the first pass, when the line containing the .EQU is encountered. so like, don't be out here referencing stuff that hasn't happened yet. π
.BYTE expr, expr, ...
assembles the bytes specified by the expression into memory. and guess what β a string may also be specified with this directive. slay! πΈ
.WORD expr, expr, ...
assembles the words specified by the expression into memory. β¨
the byte ordering used is that used by the 8031. periodt. π
.FLAG symbol1, symbol.[0-7]
sets symbol1 to the bit address specified by the symbol.[0-7] expression. and where it says [0-7], that denotes a character between 0 and 7. π¦
the resulting bit address is then checked to see if it is a valid bit address. vibe check, basically. π
.END
this directive is ignored. that's it. that's the whole tea. π
.SKIP expr
adds the value of expr to the location counter. π
it's used to reserve a block of uninitialized data, and expr should be in bytes. no cap.
β¨ LEXICAL CONVENTIONS β¨
okay bestie this is the part where we learn the grammar of the whole thing, like how you're even allowed to type numbers and words. lowkey important. let's go π
- Semicolons are a vibe killer β everything after a
;gets ignored all the way until a newline shows up. so comment away, queen. π¬ - Numbers default to decimal, unless the number starts with one of these little prefix situations:
0xor0Xβ hex time, babes. like0x00ffβ¨0bor0Bβ binary, just 1's and 0's. like0b1100110010π§0β boom, that's octal. like0377
- Numbers also default to decimal unless they end with one of these characters (suffix squad):
borBβ binary! but only if0xwasn't used up there. like1010101bhorHβ always hex. BUT if the first character is non-numerical you have to specify either0xor0first. this is so the assembler doesn't get confused and think your hex number is a symbol (she's dramatic like that π). for example:0ffh,0xffh,0XffH,20h,0x20and020hare all valid ways to specify a hexdigit. but these are not:ffh,0ff.dorDβ forces the number to decimal. unless0Xwas used. like129doorOβ makes the number get interpreted as octal. like377o
- Character constants go in single quotes like
'c'where c is some character.\b,\n,\r,\t,\'and\0are valid too. and you can drop a character constant literally anywhere an integer value would fit. slay π - Strings are a set of characters wrapped in double quotes
"". a string is only valid with the.BYTEdirective, bestie, don't try it anywhere else.\b,\n,\r,\tand\"are also valid escapes. but\0is not. π - Instructions, directives, and these specific symbols:
R0,R1,R2,R3,R4,R5,R6,R7,A,AB, andCβ you can type all of them in upper or lower case and the assembler will not be confused, no cap. These words however cannot be defined as a user symbol. any user symbol you make keeps its case exactly as written, sofooandFooare different symbols, butaddcis the same asaDdC. π - A symbol can be any alpha numerical character plus the underscore (
'_'). cute and simple. - Expressions are accepted in most places where a value or a symbol is needed. an expression is made of the following operators. all of them evaluate to integer objects (higher precedence operators listed first, iykyk):
-β Unary minus&β Bit-wise AND.|β Bit-Wise OR.*β Integer multiplication./β Integer division%β Integer modulus+β Integer addition.-β Integer subtraction.
- And one extra special icon: the symbol
'*'may be used to represent the current location counter. main character energy, honestly β
π EXAMPLES π
below is a sample assembly program. it's giving blinky lights. it's giving art. π
.org 0
start: mov P3, #0xff ; use alternate fns on P3
; leds on P1 are inverted.
setb F0 ; climbing up
mov A, #0x01 ; initial bit
write: cpl A ; write it
mov P1, A
cpl A
acall delay
jb F0, climbup ; climbing which way?
climbdn: rr A ; down - shift right
jnb ACC.0, write ; back for more
setb F0
ajmp write
climbup: rl A ; up - shift left
jnb ACC.7, write ; back for more
clr F0
ajmp write
.end ; this directive ignored.
π AUTHORS π
these two literally built the thing, show some respect bestie π«Ά
- Ken Stauffer (University of Calgary)
<stauffer@cpsc.ucalgary.ca> - Martin Langer
<martin-langer@gmx.de>
and that's the whole page, bestie!! you made it to the end, I'm so proud of you, go forth and assemble with your whole chest πβ¨ this was the AS31(1) manual page, mwah, bye ππ
π
π¦ where this page comes from
- debian bookworm: as31 2.3.1-9+b1
- debian trixie: as31 2.3.1-12
- nixos 26.05: as31 2.3.1
- nixpkgs unstable: as31 2.3.1
- ubuntu jammy: as31 2.3.1-9
- ubuntu noble: as31 2.3.1-10
- ubuntu questing: as31 2.3.1-12
- ubuntu resolute: as31 2.3.1-12build1
- ubuntu stonking: as31 2.3.1-12build1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms