CRASM(1)
π CRASM(1) π
okay bestie, sit down, hydrate, because this is the manual page for crasm β the Crasm-1.3 era one, section 1 of the manual. It's a cross assembler and it is genuinely so good at its job. Let's get into it. π«Ά
β¨ NAME β¨
crasm β Cross assembler for 6800/6801/6803/6502/65C02/Z80
π SYNOPSIS π
crasm [-o codefile] [-slx] asmfile
So the whole vibe is: you hand crasm asmfile, your microprocessor program, and it assembles it into an output file codefile, written in Intel HEX or Motorola S Code format. You also get a program listing and a symbol table printed on standard output β free extras, no cap. π
The current version of crasm can assemble programs for the 6800, 6801, 6803, 6502, 65C02, and Z80 processors. And if you wanna see the full list with your own eyes, just invoke crasm with no arguments and it prints it right out for you. β¨
π OPTIONS π
-ocodefile β names your output file. No output file is produced without this option, so like... use it, bestie.-sβ disables warnings.-lβ disables program listing output.-xβ disables symbol table output.
πΈ SYNTAX πΈ
Every line of your assembly program needs to follow one of these templates. The brackets are just marking the optional parts, they're not real characters you type:
[;comment]
label = expression [;comment]
[label] mnemonic operand [;comment]
label[;comment]
Comments are introduced by a semicolon (;) and they run all the way to the end of the line. That's it, that's the whole comment system, iconic honestly.
Labels are identifiers made of up to 36 alphanumeric characters (period and underscore count as alphanumeric here). Labels cannot start with a digit. And crasm usually does not pay attention to what column your line components start in β it's very chill about that. The one exception: if a line contains only a label and possibly a comment, then that label must start in column zero. Like, column zero specifically. Don't fight it.
What the mnemonic and operand fields look like depends on which microprocessor you selected. A few mnemonics are valid for all processors, and those are the ones you use to give directives to the assembler. Everybody calls them "pseudo-mnemonics".
π¦ Labels π¦
Labels are identifiers representing:
- an absolute address,
- a relative address (position independent code),
- a register,
- a list of registers,
- a specific bit at a specific address,
- or a mnemonic.
Most labels are composed of at most 36 alphanumeric characters, periods (.) or underscores (_). Labels cannot start with a digit. They are case insensitive β so don't stress about your caps lock. Labels that start with a period (.) are local labels, and their scope is either limited to the macro they're defined in, or limited to the code segment delimited by the pseudo-mnemonics CODE or DUMMY.
The predefined "star" label (*) represents the current program counter β that is, the address where the next assembly code instruction will be encoded. Other predefined labels include all pseudo-mnemonics, all microprocessor specific mnemonics, and register names. π
π Constants π
The assembler recognizes numerical constants expressed in decimal, hexadecimal, octal, binary, or ascii. Here's the menu:
- decimal β format
ddddβ examples:1234,675,12,1, but not0.12. - hexadecimal
$ddddβ examples:$fd12,$2AC,$0.ddddHβ examples:03H,2da7H,0FC84H, but notFC84H.0Xddddβ examples:0x03,0x2AC,0Xfc84.
- octal β format
ddddQβ examples:377Q,012412Q. - binary
%ddddβ examples:%01110110,%1100.ddddBβ examples:01110110B,1100B.0Bddddβ example:0b1100
- ascii
'cccc'β examples:'a','AB','"','\n','\''."cccc"β examples:"\t","\","a'b".
π§ Expressions π§
Just like labels, expressions can represent an absolute address (abs), a relative address for position independent code (rel), a register (reg), or a list of registers (reglist), or a reference to a specific bit at a specific address (bspec).
These are the operators it recognizes on expressions:
abs{abs}βbspecβ bit reference, e.g.pia{3}ADDR(abs)βabsβ address from a bit referenceBIT(abs)βabsβ bit number from a bit reference- absβabsβ two's complement~ absβabsβ one's complementabs << absβabsβ left shiftabs >> absβabsβ right shiftHI(abs)βabsβ high byte ((abs>>8)&$ff)LO(abs)βabsβ low byte (abs&$ff)abs | absβabsβ bitwise orabs & absβabsβ bitwise andabs ^ absβabsβ bitwise xorabs * absβabsβ multiplicationabs * absβabsβ divisionabs + absβabsβ additionrel + absβrelβ additionabs - absβabsβ subtractionrel - absβrelβ subtractionrel - relβabsβ subtractionreg - regβreglistβ register rangereglist \ regβreglistβ register list
That list is in order of decreasing precedence β so the stuff near the top binds tighter, okay? Parenthesis can be used to avoid ambiguities. And heads up: a warning is generated when an entire expression is surrounded with parenthesis and can be confused with a microprocessor addressing mode. π
Examples:
(base+$12) >> 8 & 0xff00
'A'-80H
(base+0x12)
The last example causes a warning because the parenthesis were not necessary and might suggest a microprocessor addressing mode. It's giving "extra for no reason" and crasm will notice.
All arithmetic expressions are evaluated on 32 bits. Arithmetic operations overflow silently β no drama, no message, nothing. The arithmetic values are then truncated to the size implied by the microprocessor mnemonic, and that truncation might cause a warning message.
Examples: all the following instructions
(6502) lda #$1234
(6800) ldaa $1234,x
(Z80) ld (ix+0C2H),b
cause a warning
>>> WARNING: Operand overflow
However expression
$1123454 * 1298992
overflows silently. Make it make sense π
π Pseudo-mnemonics π
The following pseudo-mnemonics are always recognized. Always always. π
CPU cpunameβ indicates the selected microprocessor type. This must appear before any microprocessor specific instruction. The possible values ofcpunameare listed when you invoke crasm without arguments, and the current list includes 6800, 6801, 6803, 6502, 65C02, and Z80.OUTPUT binformatβ indicates the format of the output file. The argumentbinformatcan take the valueSCODE, for producing an output file using Motorola's S code, orHEX, for Intel's Hex format. The default depends on the selected microprocessor.CODEβ delimits the scope of local labels and introduces a program section.DUMMYβ delimits the scope of local labels and introduces a fake program section whose sole effect is to define labels without generating code.label EQU expression/label = expressionβ define the value of labellabel. Labels defined using these directives can be redefined later in the program. (Redefine away, bestie.)[label] DB expression[,...,expression]β insert the specified data bytes (8 bits).[label] DW expression[,...,expression]β insert the specified data words (16 bits). The byte ordering depends on the selected microprocessor.[label] DL expression[,...,expression]β insert the specified data longs (32 bits). The byte ordering depends on the selected microprocessor.[label] DDB expression[,...,expression]β drops in the double bytes (that's 16 bits, bestie) for every expression you list. But watch out: the byte ordering is the opposite of the usual byte ordering for whichever microprocessor you've selected. Not a typo. It's just like that. π[label] ASC stringconstantβ inserts the ascii representation of the string stringconstant. The string must be delimited by double quotes, no negotiating. And the C escape sequences\r,\n,\t,\0,\',\", and\\are all recognized, so go off. β¨[label] DS countexpr,[valexpr]β insertscountexprbytes, every one of them holding the valuevalexpr. The default value is zero, so if you're feeling lazy you literally don't have to say anything. π«Ά[label] ALIGN EVEN[label] ALIGN ODDβ inserts a null byte specifically so the program counter lands on an even or an odd address. Alignment? Handled. πIF [expr1 [oper expr2]]β¦ELSEβ¦ENDCβ conditional assembly, the main character of pseudo-mnemonics π. The argument ofIFcan be totally empty, can be a single expressionexpr1, or can be two expressions separated by a comparison operator:>,<,>=,<=,==,!=,=, or<>. Here's the tea: the assembler processes the lines between theIFand theELSEpseudo-mnemonics if the comparisonexpr1 oper expr2is true, or if the single expressionexpr1is nonzero. Otherwise it processes the lines sitting between theELSEand theENDCpseudo-mnemonics. Conditional assembly instructions can be nested, which is giving inception fr fr. And theELSEpart can be omitted entirely. Flexible icon. πΈlabel MACROβ¦ENDMβ defines a brand new mnemonic calledlabelthat's equivalent to all the instructions living between theMACROandENDMpseudo-mnemonics. When you invoke the macro you can pass a list of comma separated operands, and inside the macro definition the character sequences\1,\2, ...\Nget replaced by the supplied operands. The character sequence\#gets replaced by the number of supplied operands. And the character sequence\*gets replaced by the unparsed macro arguments. So much power in one little backslash, I can't. πEXITMβ this pseudo mnemonic can be used inside a macro definition to exit the macro early. It's lowkey iconic when you pair it with the conditional assembly pseudo-mnemonics. πINCLUDE filenameβ forces the assembler to go process the file named filename right at the current point. Bring your friends. π¦LIST ONLIST OFFβ turns the production of a listing on or off. The default is on.CLIST ONCLIST OFFβ turns the production of a listing on or off for the non active branches of a conditional assembly construct. The default is on.ILIST ONILIST OFFβ turns the production of a listing on or off for included files. The default is off.MLIST ONMLIST OFFβ turns the production of a listing on or off for macro expansions. The default is off.NAM titleβ provides the name title for the header of the listing pages. Name your pages, they deserve it. β¨PAGEβ starts a new listing page. Fresh page, fresh vibe. πPAGE lines,columnsβ specifies the size of a listing page, with lines and columns.SKIP numberβ skips number lines. Just. Skips them. π¦FAIL messageβ generates an error message containing message. Yes bestie, you can make the assembler yell on purpose. π₯
π EXAMPLE π
Here's a small 6502 program, look at her go:
cpu 6502
cout = $fded ; display a character
* = $300 ; assemble at $300
code
pstring ldy #0
.1 lda message,y
beq .2
jsr cout
iny
.2 bne .1
rts
message asc "This is the message "
code
π CREDITS π
Leon Bottou, September 1987. Absolute legend, we stan. π
and that's the whole page, bestie!! π this gorgeous thing is from Crasm-1.3, dated 1/9/1987 β go forth and assemble something iconic. mwah π β¨
π¦ where this page comes from
- ubuntu questing: crasm 1.11-1
- ubuntu resolute: crasm 1.11-2
- ubuntu stonking: crasm 1.11-2
- Copyright (C) 1987- Leon Bottou
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms