ws goes to the data segment | .define sym Export Sym from the file | .errnz n Force error if n is nonzero | .even Align to an even address | .extern sym Declare sym external | .globl sym Same as Extern | .long n Assemble n as a long | .org adr Set Address within current segment | .short n Assemble n as a short | .space n Skip n bytes | .text What follows goes to the text segment | .word n Assemble n as a word | .zerow n Assemble n words of zeros | .include filename Include the specified file Directives: .byte 2 |0fddwi.byte f,s .ascii j0fddwi.word j .byte 6 .ascii ".align" .word ProcAlign .byte 6 .ascii ".ascii" .word ProcAscii .byte 6 .ascii ".asciz" .word ProcAsciz .byte 4 .ascii ".bss" .word NotImplemented .byte 5 .ascii ".byte" .word ProcByte .byte 5 .ascii ".data" .word NotImplemented .byte 7 .ascii ".define" .word NotImplemented .byte 6 .ascii ".errnz" .word ProcErrnz .byte 5 .ascii ".even" .word ProcEven .byte 7 .ascii ".extern" .word NotImplemented .byte 6 .ascii ".globl" .word NotImplemented .byte 8 .ascii ".include" .word ProcInclude .byte 5 .ascii ".long" .word ProcWord .byte 4 .ascii ".org" .word ProcOrg .byte 6 .ascii ".short" .word ProcWord .byte 6 .ascii ".space" .word ProcSpace .byte 5 .ascii ".text" .word NotImplemented .byte 5 .ascii ".word" .word ProcWord .byte 6 .ascii ".zerow" .word ProcZeroWords .byte 0 Instructions: .byte 4 |0fddwi.byte f,s .ascii j0fddwi.word j0fddwi.byte f,s .byte j .byte 3 .ascii "aaa" .word NothingElse .byte 55 .byte 0 .byte 3 .ascii "aad" .word NothingElse .byte 213 .byte 10 .byte 3 .ascii "aam" .word NothingElse .byte 214 .byte 10 .byte 3 .ascii "aas" .word NothingElse .byte 63 .byte 0 .byte 3 .ascii "adc" .word AddType .byte 21 .byte 17 .byte 5 .ascii "adcb" .byte 0 .word AddType .byte 20 .byte 16 .byte 3 .ascii "add" .word AddType .byte 5 .byte 1 .byte 5 .ascii "addb" .byte 0 .word AddType .byte 4 .byte 0 .byte 3 .ascii "and" .word AddType .byte 37 .byte 33 .byte 5 .ascii "andb" .byte 0 .word AddType .byte 36 .byte 32 .byte 4 .ascii "call" .word JmpCallType .byte 232 .byte 16 .byte 5 .ascii "callf" .word JmpCallFarType .byte 0154 .byte 24 .byte 3 .ascii "cbw" .word NothingElse .byte 152 .byte 0 .byte 3 .ascii "clc" .word NothingElse .byte 248 .byte 0 .byte 3 .ascii "cld" .word NothingElse .byte 252 .byte 0 .byte 3 .ascii "cli" .word NothingElse .byte 250 .byte 0 .byte 3 .ascii "cmc" .word NothingElse .byte 245 .byte 0 .byte 3 .ascii "cmp" .word AddType .byte 61 .byte 57 .byte 5 .ascii "cmpb" .byte 0 .word AddType .byte 60 .byte 56 .byte 5 .ascii "cmpsb" .word NothingElse .byte 166 .byte 0 .byte 5 .ascii "cmpsw" .word NothingElse .byte 167 .byte 0 .byte 3 .ascii "cwd" .word NothingElse .byte 153 .byte 0 .byte 3 .ascii "daa" .word NothingElse .byte 39 .byte 0 .byte 3 .ascii "das" .word NothingElse .byte 47 .byte 0 .byte 3 .ascii "dec" .word IncDecType .byte 72 .byte 8 .byte 5 .ascii "decb" .byte 0 .word RegOrMem .byte 254 .byte 8 .byte 3 .ascii "div" .word DivMulRegMem .byte 247 .byte 48 .byte 5 .ascii "divb" .byte 0 .word DivMulRegMem .byte 246 .byte 48 .byte 3 .ascii "esc" .word NothingElse .byte 216 .byte 0 .byte 3 .ascii "hlt" .word NothingElse .byte 244 .byte 0 .byte 4 .ascii "idiv" .word DivMulRegMem .byte 247 .byte 56 .byte 6 .ascii "idivb" .byte 0 .word DivMulRegMem .byte 246 .byte 56 .byte 4 .ascii "imul" .word DivMulRegMem .byte 247 .byte 40 .byte 6 .ascii "imulb" .byte 0 .word DivMulRegMem .byte 246 .byte 40 .byte 2 .ascii "in" .word InOutPort .byte 229 .byte 0 .byte 4 .ascii "inb" .byte 0 .word InOutPort .byte 228 .byte 0 .byte 3 .ascii "inc" .word IncDecType .byte 64 .byte 0 .byte 5 .ascii "incb" .byte 0 .word RegOrMem .byte 254 .byte 0 .byte 3 .ascii "int" .word OneByteOnly .byte 205 .byte 0 .byte 4 .ascii "int3" .word NothingElse .byte 204 .byte 0 .byte 4 .ascii "into" .word NothingElse .byte 206 .byte 0 .byte 4 .ascii "iret" .word NothingElse .byte 207 .byte 0 .byte 2 .ascii "ja" .word OneRelativeLabel .byte 119 .byte 0 .byte 3 .ascii "jae" .word OneRelativeLabel .byte 115 .byte 0 .byte 2 .ascii "jb" .word OneRelativeLabel .byte 114 .byte 0 .byte 2 .ascii "jc" .word OneRelativeLabel .byte 114 .byte 0 .byte 4 .ascii "jcxz" .word OneRelativeLabel .byte 227 .byte 0 .byte 2 .ascii "je" .word OneRelativeLabel .byte 116 .byte 0 .byte 2 .ascii "jg" .word OneRelativeLabel .byte 127 .byte 0 .byte 3 .ascii "jge" .word OneRelativeLabel .byte 125 .byte 0 .byte 2 .ascii "jl" .word OneRelativeLabel .byte 124 .byte 0 .byte 3 .ascii "jle" .word OneRelativeLabel .byte 126 .byte 0 .byte 3 .ascii "jmp" .word JmpCallType .byte 233 .byte 32 .byte 4 .ascii "jmpf" .word JmpCallFarType .byte 234 .byte 40 .byte 4 .ascii "jmps" .word OneRelativeLabel .byte 235 .byte 0 .byte 3 .ascii "jna" .word OneRelativeLabel .byte 118 .byte 0 .byte 3 .ascii "jnb" .word OneRelativeLabel .byte 115 .byte 0 .byte 3 .ascii "jnc" .word OneRelativeLabel .byte 115 .byte 0 .byte 3 .ascii "jne" .word OneRelativeLabel .byte 117 .byte 0 .byte 3 .ascii "jnz" .word OneRelativeLabel .byte 117 .byte 0 .byte 3 .ascii "jno" .word OneRelativeLabel .byte 113 .byte 0 .byte 3 .ascii "jnp" .word OneRelativeLabel .byte 123 .byte 0 .byte 3 .ascii "jns" .word OneRelativeLabel .byte 121 .byte 0 .byte 2 .ascii "jo" .word OneRelativeLabel .byte 112 .byte 0 .byte 2 .ascii "jp" .word OneRelativeLabel .byte 122 .byte 0 .byte 2 .ascii "js" .word OneRelativeLabel .byte 120 .byte 0 .byte 2 .ascii "jz" .word OneRelativeLabel .byte 116 .byte 0 .byte 4 .ascii "lahf" .word NothingElse .byte 159 .byte 0 .byte 3 .ascii "lds" .word RegisterMemory .byte 197 .byte 0 .byte 3 .ascii "lea" .word RegisterMemory .byte 0141 .byte 0 .byte 3 .ascii "les" .word RegisterMemory .byte 196 .byte 0 .byte 4 .ascii "lock" .word NothingElse .byte 240 .byte 0 .byte 5 .ascii "lodsb" .word NothingElse .byte 172 .byte 0 .byte 5 .ascii "lodsw" .word NothingElse .byte 173 .byte 0 .byte 4 .ascii "loop" .word OneRelativeLabel .byte 226 .byte 0 .byte 5 .ascii "loopz" .word OneRelativeLabel .byte 225 .byte 0 .byte 6 .ascii "loopnz" .word OneRelativeLabel .byte 224 .byte 0 .byte 3 .ascii "mov" .word MovType .byte 1 .byte 0 .byte 5 .ascii "movb" .byte 0 .word MovType .byte 0 .byte 0 .byte 5 .ascii "movsb" .word NothingElse .byte 164 .byte 0 .byte 5 .ascii "movsw" .word NothingElse .byte 165 .byte 0 .byte 3 .ascii "mul" .word DivMulRegMem .byte 247 .byte 32 .byte 5 .ascii "mulb" .byte 0 .word DivMulRegMem .byte 246 .byte 32 .byte 3 .ascii "neg" .word RegOrMem .byte 247 .byte 24 .byte 5 .ascii "negb" .byte 0 .word RegOrMem .byte 246 .byte 24 .byte 3 .ascii "nop" .word NothingElse .byte 0144 .byte 0 .byte 3 .ascii "not" .word RegOrMem .byte 247 .byte 16 .byte 5 .ascii "notb" .byte 0 .word RegOrMem .byte 246 .byte 16 .byte 2 .ascii "or" .word AddType .byte 13 .byte 9 .byte 4 .ascii "orb" .byte 0 .word AddType .byte 12 .byte 8 .byte 3 .ascii "out" .word InOutPort .byte 231 .byte 0 .byte 5 .ascii "outb" .byte 0 .word InOutPort .byte 230 .byte 0 .byte 3 .ascii "pop" .word PushPopType .byte 143 .byte 9 .byte 4 .ascii "popf" .word NothingElse .byte 157 .byte 0 .byte 4 .ascii "push" .word PushPopType .byte 255 .byte 48 .byte 5 .ascii "pushf" .word NothingElse .byte 156 .byte 0 .byte 3 .ascii "rcl" .word ShiftRotate .byte 209 .byte 16 .byte 5 .ascii "rclb" .byte 0 .word ShiftRotate .byte 208 .byte 16 .byte 3 .ascii "rcr" .word ShiftRotate .byte 209 .byte 24 .byte 5 .ascii "rcrb" .byte 0 .word ShiftRotate .byte 208 .byte 24 .byte 3 .ascii "rep" .word NothingElse .byte 243 .byte 0 .byte 4 .ascii "repz" .word NothingElse .byte 243 .byte 0 .byte 5 .ascii "repnz" .word NothingElse .byte 242 .byte 0 .byte 3 .ascii "ret" .word ReturnType .byte 195 .byte 194 .byte 4 .ascii "retf" .word ReturnType .byte 203 .byte 202 .byte 3 .ascii "rol" .word ShiftRotate .byte 209 .byte 0 .byte 5 .ascii "rolb" .byte 0 .word ShiftRotate .byte 208 .byte 0 .byte 3 .ascii "ror" .word ShiftRotate .byte 209 .byte 8 .byte 5 .ascii "rorb" .byte 0 .word ShiftRotate .byte 208 .byte 8 .byte 4 .ascii "sahf" .word NothingElse .byte 158 .byte 0 .byte 3 .ascii "sal" .word ShiftRotate .byte 209 .byte 32 .byte 5 .ascii "salb" .byte 0 .word ShiftRotate .byte 208 .byte 32 .byte 3 .ascii "sar" .word ShiftRotate .byte 209 .byte 56 .byte 5 .ascii "sarb" .byte 0 .word ShiftRotate .byte 208 .byte 56 .byte 3 .ascii "sbb" .word AddType .byte 29 .byte 25 .byte 5 .ascii "sbbb" .byte 0 .word AddType .byte 28 .byte 24 .byte 5 .ascii "scasb" .word NothingElse .byte 174 .byte 0 .byte 5 .ascii "scasw" .word NothingElse .byte 175 .byte 0 .byte 3 .ascii "seg" .word SegmentRegister .byte 38 .byte 0 .byte 3 .ascii "shl" .word ShiftRotate .byte 209 .byte 32 .byte 5 .ascii "shlb" .byte 0 .word ShiftRotate .byte 208 .byte 32 .byte 3 .ascii "shr" .word ShiftRotate .byte 209 .byte 40 .byte 5 .ascii "shrb" .byte 0 .word ShiftRotate .byte 208 .byte 40 .byte 3 .ascii "stc" .word NothingElse .byte 249 .byte 0 .byte 3 .ascii "std" .word NothingElse .byte 253 .byte 0 .byte 3 .ascii "LMNsti" .word NothingElse .byte 251 .byte 0 .byte 5 .ascii "stosb" .word NothingElse .byte 170 .byte 0 .byte 5 .ascii "stosw" .word NothingElse .byte 171 .byte 0 .byte 3 .ascii "sub" .word AddType .byte 45 .byte 41 .byte 5 .ascii "subb" .byte 0 .word AddType .byte 44 .byte 40 .byte 4 .ascii "test" .word AddType .byte 199 .byte 133 .byte 6 .ascii "testb" .byte 0 .word AddType .byte 199 .byte 132 .byte 4 .ascii "wait" .word NothingElse .byte 0155 .byte 0 .byte 4 .ascii "xchg" .word XchgType .byte 199 .byte 135 .byte 6 .ascii "xchgb" .byte 0 .word XchgType .byte 199 .byte 134 .byte 4 .ascii "xlat" .word NothingElse .byte 215 .byte 0 .byte 3 .ascii "xor" .word AddType .byte 53 .byte 49 .byte 5 .ascii "xorb" .byte 0 .word AddType .byte 52 .byte 48 .byte 0 |End of symbols.asm AddressingModes: .byte 1 |0fddwi.byte f,s .ascii j0fddwi.byte j .byte 5 .ascii "bx_si" .byte 00 .byte 5 .ascii "bx_di" .byte 01 .byte 5 .ascii "bp_si" .byte 02 .byte 5 .ascii "bp_di" .byte 03 .byte 2 .ascii "si" .byte 04 .byte 2 .ascii "di" .byte 05 .byte 2 .ascii "bp" .byte 06 .byte 2 .ascii "bx" .byte 07 .byte 0 BigRegisters: .byte 1 .byte 2 .ascii "ax" .byte 0 .byte 2 .ascii "cx" .byte 1 .byte 2 .ascii "dx" .byte 2 .byte 2 .ascii "bx" .byte 3 .byte 2 .ascii "sp" .byte 4 .byte 2 .ascii "bp" .byte 5 .byte 2 .ascii "si" .byte 6 .byte 2 .ascii "di" .byte 7 .byte 0 SmallRegisters: .byte 1 .byte 2 .ascii "al" .byte 0 .byte 2 .ascii "cl" .byte 1 .byte 2 .ascii "dl" .byte 2 .byte 2 .ascii "bl" .byte 3 .byte 2 .ascii "ah" .byte 4 .byte 2 .ascii "ch" .byte 5 .byte 2 .ascii "dh" .byte 6 .byte 2 .ascii "bh" .byte 7 .byte 0 SegmentRegisters: .byte 1 .byte 2 .ascii "es" .byte 0 .byte 2 .ascii "cs" .byte 1 .byte 2 .ascii "ss" .byte 2 .byte 2 .ascii "ds" .byte 3 .byte 0 |Fields of the entry in the symbol table symtab idname = 0 |word pointing to name in the string table DefFileNameOffset = 2 |word pointing to name of file where defined DefLineNumber = 4 |word pointing to line number where defined Attributes = 6 |Attributes of the symbol - defined below Value = 8 |Value of the variable - only word lengths size_syment = 10 Calculated = 0x0008 IsDefined = 0x0004 IsFake = 0x0002 IsEquate = 0x0001 NeverDefined = 0x0010 NotCalculated = 0xFFF7 |This procedure gets a word from the input, actually it gets a token. |When a carriage return is found, the linecount is incremented | | | GetWord: call GetToken jc GetWordEnd movb al,InputWord call IsAlphaDotAL jnc InvalidStart clc GetWordEnd: ret InvalidStart: mov bx,#BadStartMessage call PanicRecover GetToken: push ax push bx push cx push dx push si push di call IgnoreSpaces jc GetTokenEnd mov di,#InputWord call GetChar jc GetTokenEnd call IsAlphaNumDotAL jnc NonAlphaNumeric call IsNumAL jnc MustBeWord |Only Numbers come here. |Numbers may be decimal,hexadecimal cmpb al,#'0' |leading digit is not zero - decimal jnz GetNumber stosb call GetChar cmpb al,#'X' |for hex jz GetHexNumber cmpb al,#'x' jz GetHexNumber call UnGetChar jmps GetNumber1 GetNumber: stosb GetNumber1: call GetChar jc NumberEnded1 call IsNumAL jc GetNumber NumberEnded: call UnGetChar NumberEnded1: clc GetTokenEnd: | pushf | mov bx,#InputWord | call DisplayOtherMessage | call DisplayMessage | db 'is the token got',0dh,0ah,0 | popf pushf xorb al,al stosb popf pop di pop si pop dx pop cx pop bx pop ax ret MustBeWord: stosb cmp di,#InputWord+WordSize| jnz StartWordSizeStillOK |If the identifier is too large then mov bx,#IdentLargeMessage |crib and come out call PanicRecover | StartWordSizeStillOK: | call GetChar jc WordEnded call IsAlphaNumDotAL |Succeeding can be als,nums,dots jc MustBeWord |If yes store them too call UnGetChar WordEnded: clc jmps GetTokenEnd GetHexNumber: orb al,#'a' - 'A' |downcase it, for later GetHexNumber1: stosb call GetChar jc NumberEnded1 call IsHexAL jc GetHexNumber1 jmps NumberEnded LostQuote: mov bx,#MissingQuoteMessage call PanicRecover NonAlphaNumeric: cmpb al,#''' jnz OnlyThisChar stosb call GetChar jc LostQuote stosb call GetChar jc LostQuote cmpb al,#''' jnz LostQuote stosb clc jmps GetTokenEnd OnlyThisChar: cmpb al,#'|' jz CommentStartIgnore stosb clc jmps GetTokenEnd CommentStartIgnore: call UnGetChar clc jmps GetTokenEnd IgnoreSpaces: call GetChar jc IgnoreSpacesEnd cmpb al,#' ' jz IgnoreSpaces cmpb al,#' ' jz IgnoreSpaces call UnGetChar clc IgnoreSpacesEnd: ret GetComma: cmpb InputWord,#',' jz GetCommaEnd push si call IgnoreSpaces jc GetCommaNo call GetChar cmpb al,#',' jz GetCommaYes GetCommaNo: mov bx,#CommaMessage call PutExpectedMessage GetCommaYes: pop si GetCommaEnd: ret | Assemble an instruction GetInstruction: mov si,#Instructions call MatchKeyword jc InstructionNoMatch mov ax,[si] inc si inc si call ax clc InstructionNoMatch: ret |IsAlphaAL |This function returns carry if A is alphabetic else it returns no carry IsAlphaAL: cmpb al,#'A' |First check whether it is in jc LessThanBigA |the capital letters of the alphabet cmpb al,#'[' |if >= A & <= Z then it is a valid jc WhatWeWant |character LessThanBigA: |Now checking for the lower case cmpb al,#'a' |if >= a jc LessThanSmallA |and <= z cmpb al,#'{' |then too it is a valid jc WhatWeWant |character LessThanSmallA: |If neither uppercase or lower cmpb al,#'_' |case then check for an underscore jnz NotWhatWeWant |The underscore is also treated stc |as an alphabetic character WhatWeWant: ret NotWhatWeWant: | clc ret IsNumAL: cmpb al,#'0' jc NotWhatWeWant cmpb al,#':' ret IsHexAlphaAL: cmpb al,#'A' jc NotWhatWeWant cmpb al,#'G' jc WhatWeWant cmpb al,#'a' jc NotWhatWeWant cmpb al,#'g' jnc NotWhatWeWant subb al,#'a' - 'A' stc ret |Surprise - converts to uppercase as well if a hex alphabet to take care. IsHexAL: call IsNumAL jc WhatWeWant call IsHexAlphaAL ret IsAlphaDotAL: call IsAlphaAL jc WhatWeWant cmpb al,#'.' jnz NotWhatWeWant stc ret IsAlphaNumDotAL: call IsAlphaDotAL jc WhatWeWant call IsNumAL ret |This function is called, when all the arguments of the current line |have been processed. i.e. when no more arguments are needed. This is |called before each statement is processed. It processes the comment |to the end of the line, if any, consumes the newline, skips to the |next line, If that line is empty (contains only white spaes) or |contains just a comment (with or without leasing spaces) then the |line is also consumed. This continues till a line, with a non- |comment, non whitespace start is found. The procedure also eats up |characters till the first non-white space character on that line. GetEndOfLine: | xor bp,bp |No line end found GetEndOfLine1: |In case of start of file call GetChar |Get the next input character jnc NotYetEofForEol |If EOF then abort inc bp |EOF also valid end of stmt. stc jmps GetEndOfLineEnd NotYetEofForEol: cmpb al,#' ' |If it is a space then consume jz GetEndOfLine1 |the space and continue cmpb al,#' ' |Do the same even if you jz GetEndOfLine1 |encounter a TAB character. cmpb al,#CR |Reached end of line on the input jz GetEndOfLine1 |Discard any carriage returns that cmpb al,#LF |were there in the input. So also jnz NoLine |the line feeds inc bp inc InputLineNumber jmps GetEndOfLine1 NoLine: cmpb al,#'|' |Is it the start of a comment? jz CommentStarted |If it isn't then we put back the call UnGetChar |extra character that we got. clc |Signal that a line was found GetEndOfLineEnd: |to the caller lahf or bp,bp |If a line end wasn't found jnz HadFoundEnd |then error mov bx,#ExtraCharsMessage |that extra characters were there call PanicRecover |at the end of line HadFoundEnd: | sahf ret |and get back. CommentStarted: |A UNIX pipe character was found call GetChar |Get the mext input character jc GetEndOfLineEnd |EOF found on the input cmpb al,#CR |If we reach a carraige return jz GetEndOfLine1 |it means that the comment ended cmpb al,#LF |So also for a linefeed (MINIX) jnz CommentStarted |So we start processing the next line inc InputLineNumber jmps GetEndOfLine1 |Else we continue till the end of |this line. |This function reads a character from a file, The input is buffered by the |InputBuffer. The function keeps track of where it is by keeping two pointers. |The InputBufferReadPtr (points to the character that has to be read) and |the InputBufferEndPtr (points beyond the last character that was read). If the |InputBufferReadPtr reaches the InputBufferEndPtr, then the characters in the |buffer have all been read. The buffer has to be loaded agein from the file. | |Destroys a lot of things | |Returns : No carry and character in al if successful | Carry if unsuccessful GetChar: mov ax,InputBufferReadPtr |If the read ptr is the same as the end cmp ax,InputBufferEndPtr |ptr, it means that all the characters jz InputBufferFinished |in the buffer have been read mov si,ax |If not then load the next character lodsb |and save the new read ptr mov InputBufferReadPtr,si | cmpb al,#26 |Not for MINIX. 1A means eof jz GetAtEndOfFile |for dos clc ret InputBufferFinished: movb ah,#ReadFunction |DOS function read from a file into the mov bx,InputFileHandle |input buffer. mov cx,#BufferSize mov dx,#InputBuffer int #DosInterrupt jnc BufferReadWasOK |If there was an error, then panic mov bx,#ErrorReadingInputMessage call Panic BufferReadWasOK: cmp ax,#0 |else if no chars were read, then jnz NotEndOfFile |it means that the end of file was GetAtEndOfFile: stc |reached. Return a carry to show that ret |couldn't return a value. NotEndOfFile: |If some characters were read, then mov si,#InputBuffer |the pointers to the beginning and add si,ax |the end of the buffer are made right mov InputBufferEndPtr,si |ax has the number of characters that sub si,ax |were read. Get the first character lodsb |into al, mov InputBufferReadPtr,si |Adjust the start buffer clc |Return success ret | UnGetChar: dec InputBufferReadPtr ret BackupInputWord: push si push di push cx mov si,#InputWord mov di,#BackupWord InputWordMoveEnd: mov cx,#WordSize rep movsb pop cx pop di pop si ret RestoreInputWord: push si push di push cx mov si,#BackupWord mov di,#InputWord jmp InputWordMoveEnd Version 1.9 7297 bytes 1. Fixed a dangerous bug - forward relative jumps of (128-255) were being allowed and actually coded as 0x80 to 0xFF, which worked out to be backward jumps - symtab.s Version 1.8 7295 bytes 1. Stole a few bytes by defining the extensions as words in ax before storing them Version 1.7 1. Added the binary operator !, which takes two byte constants and makes them into a word 2. Fixed bugs with the ! operator (lower byte duplicated) 3. Fixed bugs with non-error reporting of backword jumps of more than 128 bytes. (Misplaced label on too large operand) Version 1.6 1. Added a variable SavedStackPointer that keeps track of the stack for each assemble file. Filled in Assemble in asm.s. Also in direct.s, it is pushed and popped for include files to keep stack consistency. 2. Added some error recovery - only one type - resync at end of line Stack Pointer is restored to where it was. List file may contain junk. Don't know as yet. Still aborts on severe errors. The undefined error messsage in symtab.s had to be treated specially. Output file is still generated. 3. Fixed the include error message. Instead of showing the name of the included file in the error message, It shows the name of the file in which the failed include statement occured. Fixes to direct.s and reorganization to OpenInputFile in asm.s 4. Added a never defined flag so that the assembler can continue with assembly even if a symbol is not defined. Set in symtab.s 6. Added the not operator to the expression evaluation section - expr.s For a new operator the procedure is a. add the operator in IsOperator in the right place b. if the operator is unary, add it in the IsUnaryOperator too. c. add the code to evaluate it in Evaluate expression 7. Allows byte sized values to have 0 or ff as higher byte - to accomodate the unary not, else !0x80 was not allowed as a byte operand. Changes to support.s Version 1.5 1. Modified symtab.s to add a function RecordXref that puts the index of symbol, filename and line no into the list file 2. Modified expr.s so that it calls RecordXref in the middle of processing an expression - only for real variables - not constants or fakes. 3. Modified lister to report number of references to each variable and to list the references symbolwise 4. Removed redundant code in asm primarily Is8bitregister and Is16bitRegister in support.s 5. Removed redundant equates and Messages - size mismatch Version 1.4 1. Instead of printing the symbol table onto the screen it puts the symbol table onto the list file. 2. The list file has the symbol table proper and the string table 3. To make data structures common to the assembler and the lister and to prevent duplication of work, two include files have been created. dos.i with the equates for DOS functions and symtab.i with the structures for the symbol table. 4. The message displaying functions have been separated out to another file called display.s. 5. The functions in display.s (except for PutCarriageReturn and DisplayRegister) now keep track of the number of characters that have been displayed. 6. The symbol table being dumped on the screen is disabled, only the .lst file is created. ListSymbols from symtab.s was deleted. and the call from asm.s 7. A separate program lister was added which prints out the symbol table from the .lst file 8. display.s was putting out a LF and a CR in that order, which was confusing editors - e.g. MKS vi. Version 1.3 1. The filenames are directly put into the string space instead of present filename a. One variable presentfilename is removed - save space b. Changes to asm.s and direct.s (for includes) 2. The print stats function was removed 3. The output filename is accessible throughout the programs execution 4. The output file is deleted if an error in assembly is detected. 5. Can handle infinite (Promises!) path length one error message removed - path too long. message.s 6. Opens List file too. The list file name is on the string table too. added two variables - ListFileHandle and ListFileNameOffset 7. Doesn't print the name of the file that it is assembling any longer. or the names of the output files. 8. Doesn't display assembly successful at the end either. - silent on success. Version 1.2 1. Accepts char constants - in single quotes, wherever constants are allowed. 2. Accepts hex constants - prefixed by 0x, with overflow checking. 3. Accepts negative byte constants - complained earlier. | .ascii str assemble a string QuoteExpected: mov bx,#QuotesMessage call PutExpectedMessage ProcAscii: call IgnoreSpaces call GetChar jc QuoteExpected cmpb al,#'"' jnz QuoteExpected MoreStringChars: call GetChar jc QuoteExpected cmpb al,#'"' jz EndOfString cmpb al,#LF jz QuoteExpected call OutputByte jmps MoreStringChars EndOfString: ret | .asciz str assemble a zero terminated string ProcAsciz: call ProcAscii xorb al,al call OutputByte ret | .align n align on multiple of n bytes ProcAlign: call GetATNumber jc ATVError mov bx,ax mov ax,LocationCounter xor dx,dx div bx or dx,dx jnz AlignNeed ret AlignNeed: sub bx,dx mov ax,LocationCounter add ax,bx jmps OrgEnd | .bss What follows goes to the bss segment | .byte n Assemble one or more bytes ProcByte: call GetATNumber orb ch,ch jz ByteEvaluated xor ax,ax ByteEvaluated: call CheckForSize call OutputByte ret | .data What follows goes to the data segment | .define sym Export Sym from the file | .errnz n Force error if n is nonzero ProcErrnz: call GetATNumber jc ATVError or ax,ax jnz AssertError ret AssertError: mov bx,#NonZeroMessage call PanicRecover | .even Align to an even address ProcEven: mov ax,LocationCounter testb al,#1 jz EvenEnd inc ax jmps OrgEnd EvenEnd: ret | .extern sym Declare sym external | .globl sym Same as Extern | .org adr Set Address within current segment ProcOrg: call GetATNumber jc ATVError OrgEnd: mov LocationCounter,ax add ax,#OutputStart mov PresentOutputOffset,ax call CheckOutputOverflow ret | .space n Skip n bytes ProcSpace: call GetATNumber jc ATVError mov cx,ax MoreSpaces: call OutputByte loop MoreSpaces ret | .text What follows goes to the text segment | .long n Assemble n as a long | .short n Assemble n as a short | .word n Assemble n as a word ProcWord: call GetATNumber call OutputWord ret | .zerow n Assemble n words of zeros ATVError: mov bx,#ATVErrorMessage call PanicRecover GetATNumber: mov bx,#0 call GetOperand mov ax,bx cmpb cl,#Disp jnz ATVError orb ch,ch jnz NotEvaled stc ret NotEvaled: clc ret ProcZeroWords: call GetATNumber mov cx,ax xor ax,ax MoreZeroWords: call OutputWord loop MoreZeroWords ret | .include filename include the specified filename ProcInclude: call GetToken push SavedStackPointer push InputFileHandle push InputLineNumber push InputBufferReadPtr push InputBufferEndPtr mov si,#InputBuffer mov cx,#BufferSize/2 pushloop: lodsw push ax loop pushloop push PresentFileNameOffset |Must be last to be pushed - popped on failure mov di,StringSpace mov PresentFileNameOffset,di mov si,#InputWord IncludeMoreChars: lodsb stosb orb al,al jnz IncludeMoreChars call CheckStringTableOverflow mov StringSpace,di call OpenInputFile jc IncludeFileError call Assemble call CloseInputFile pop PresentFileNameOffset mov di,#InputBuffer + BufferSize - 2 mov cx,#BufferSize/2 std poploop: pop ax stosw loop poploop cld pop InputBufferEndPtr pop InputBufferReadPtr pop InputLineNumber pop InputFileHandle pop SavedStackPointer ret IncludeFileError: pop PresentFileNameOffset |The only thing destroyed as yet mov bx,#IncludeFileErrorMessage call PanicRecover S ...l;ǃ;CdEEPj! ;ueMeE%0EEE EPjj:C`@$`wCEࠡuE$bE jVj hjj jjj Shj?$1e[^_]ÐUh耓 h%hbhdY h%hqhcB h%hj .1Ív'US ]U RClP詢KE ClE]{t&'UVSu] PFlPfZY^PNlQDe[^]Ð&US ]RClP*KDPClP]ÍUS ]RClPKPKlQĠ]Ív'UWVS(E PkXEPhjjE P$i E@1Džu fCUB9~IUBlM9H ~WVQP>MBEECUB9U`Dž1ۿ>h,BPRE PfhDž؃tXCGM9q~s j jjju Vf 9`th,jjE Ph؃u j jjjE Pqf CGM9qt& j jjjM QLfj jjjU R8f E@Iv'ރ PjPDPE Pe CU9r~JC9T j jBPRE PeDž CU9rSjjM Q9eE9HEe[^_]É' jQRPE P(j 9. j jjju Vdރ UDžDžpE`DžUt&US ]E PS u#CCC C$C4]Í'UEU ~ QPRHlQÍ'RPQPlRҳÐUWV;;"; ; h;XZh"h1e^_]Ðt&UWVSEPEPEPUBlP}艽^_ESHlQE1DžDžDž|EVMRURPE@lPȲ^X]SUJlQ薳EZuVPhP]SZ1ۍ t&'% t u t t+~.PSW}wlVR)؉9~UZDtF;z<|;]E jSRE@lPfUB<);~ɋ]ރ@vW'߸ j@VPE@lP@@~k@w߃r tf t VSSUJlQ胷U:e[^_]Ð)t[:EDž{&uffDž*v'? 'gUR@) UB@+|11CA9~0% uE@uEeEPEPE)PV}MU jE)PR蒲EEE10&'eEPEP)RV(MU] u%O ] /uh&>WU uRj)PS虱U>3EƉƒ8 6]EPUx QShSRtًE u%'E t >uERjE)PVHe[^_]ÍËE tD E tc-u8-ux>uEEQj)PSqUBEUtXt_EESj)RV,UPVhUMQ(EEFE:x-CEEUWVS uE EUUMMV~K11 t&C9~#FxtPURUGVC9݅te[^_]ÍEx9U}FUE MMMe[^_]፶UWVL`LL[L L0L hLs_Xh[h DY^jh 61e^_]Í'UWVS]Ejha诈 jMQRPb#E jhLPUBhHM~QxClpl1 C;]}/VPuPjSE@lP#UEMAe[^_]Ív'\&US]ChP] pL]t&'UWVSNjphV[ u.v'[htC uClPV覮[hulQW RjW輛F~>1PFPhW:VB9th/WVC9če[^_]ÍUVS]sh S\Sh`PV ؍e[^] US ]E PSlL1]Í'UE ]s)vUWVSu^hVƒx;C| e[^_]Ðt& CPǃt؃ VÃtƃjVxXZWS/e[^_]ÐUME uA A]Ít&'PvP؃wA8 ‰Q]ÍvA ‰Q]UUJH%BHtVBlH\ytJAu>&'$t&A(;BluBHtA$u␍&]Í&'UWV<<<<<<<`< =` = h<VoXZhh ^_jh !1e^_]Í&'UWVS(hƃ `!EE F ;E}vPWEPVD uE1ېt&PWEPV@ :wɋ@C뷍&E}눍t&E%S}WPV艓]EEQSURVn uEh =Pu~UfhEPO e[^_]Ít&1vD"Pt\BPWEPVƒ:u؅~;d!gd!PRhh =`!Auuf$ti9plu獴&huV ;& hƃhEPU PEPJ)^_SMQ:US ]C<C4CHjSYCT@1]Ít&'UWVS,]E@lEԋ@\E؋P,U܋EM E4 ;usM9Q t Љ]jEPSUR } URSEPF u+u e[^_]Í&'UWVS lj։˅yCt&'~,)Å~$PSVQyu t݃t؍e[^_]à R&UEU HHuM ~" tmRP_Ðt&t; u PÐ&@l@\UUÐ& P6f PwfjPLà PafUEPHu PW7f@l@\EUÍ&UEHHu Pwbf@l@\EUYÍ&UEU HHt0@l@\~]&]U E]t&UEU HHt0@l@\~]]U E]tt&UWVSHhǃ P W WSPhS,VhjWfEPfEfEPfE EPhTW@G:U1e[^_]Ív WQhjjUЍt&'Eቅ@ffJG}־KffUG URPXDž#pDֈD/0t&DֈDjEPZǃx!jURt, WFuufVEi&e[^_]莿Dž~1 VMF9jS$$XZPW$\UWVSujh0|ǃEPW~|$4袿ÃG\G`PCPhFWx{(Cs0C$CC 8C8uK CPًUE xpPSh@P葽 ShCPϿe[^_]fjhV1{ƃt8@<PShWws,끍 Ww1뤃 Wg$1댐&US ]hlzt@hS`!d!EEE EEjEPhh9t PSh]US ]h^lƒtcUEjEPRht4PS jh<S ZYhS <]Ð&떉'UWVSP]hPPݾDžf1ɈS$u6< H< &'{tJAu>&'$t&C(;BlurHtC$u␍&98 hA#A$Pe[^_]Ðt&[C$[t&'qЃ w(C jVGl` ̍&SVe[^_]Ít&'SVf 떐US ]M QSlLXZCllPS1]ÐS[(1tPjt$Y [USЃuX[]ÐUS语Û(設[]РP p-0-A----`-self-insert-commandvopen-lineprevious-linevnext-linevbackward-charvforward-charvbackward-wordvforward-wordvscroll-downvscroll-upvbeginning-of-lineend-of-lineoverwrite-modedelete-charbackward-delete-charbackward-delete-wordvdelete-wordvkill-linevset-mark-commandkill-regionvcopy-regionvbeginning-of-bufferend-of-bufferexecute-extended-commands{Command: }[command]|command|iuniversal-argumentyankyank-poptabulatequoted-insertsave-buffervwrite-filevsuspend-emacsfind-files{Find file: }[file]|file|find-alternate-files{Find alternate file: }[file]|file|switch-to-buffers{Switch to buffer: }[buffer]|buffer|kill-buffers{Kill buffer: }[buffer]|buffer|insert-files{Insert file: }[file]|file|abortdoctorisearch-forwardvisearch-backwardvquery-replaces{Query replace: }|search|s{With: }|replace|undonewlinerefreshgoto-linei{Goto line: }goto-chari{Goto char: }iglobal-set-keys{Set key globally: }s{command: }[command]|command|vc-toggle-read-onlyfill-paragraphbackward-paragraphforward-paragraphexchange-point-and-markdowncase-wordvupcase-wordvdowncase-regionvupcase-regionvstart-kbd-macroend-kbd-macrocall-last-kbd-macroother-windowdelete-windowvdelete-other-windowssplit-window-verticallyvsplit-window-horizontallyvhelp-for-helpdescribe-bindingsdescribe-key-brieflyset-buffer-file-coding-systems{Charset: }[charset]convert-buffer-file-coding-systems{Charset: }[charset]toggle-bidirset-input-methods{Input method: }[input]switch-input-methodset-styles{Style: }[style]|style|s{CSS Property Name: }s{CSS Property Value: }set-display-sizei{Width: }i{Height: }set-system-fontsstoggle-full-screentoggle-mode-linetoggle-line-numberstruncate-linesword-wrapset-tab-widthi{Tab width: }set-indent-widthi{Indent width: }set-indent-tabs-modei{Indent tabs mode (0 or 1): }minibuffer-exitvminibuffer-abortvminibuffer-completeminibuffer-complete-spaceprevious-history-elementvnext-history-elementvless-exitless-isearchvQEmacs version 0.3.1, Copyright (c) 2000-2003 Fabrice Bellard%s:%d: badly defined command '%s' QEmacs help for help - Press q to quit: C-h C-h Show this help C-h b Display table of all key bindings C-h c Describe key briefly Buffer %s modified; kill anyway? (yes or no) Mark saved where search startedSave file %s? (y, n, !, ., q) Modified buffers exist; exit anyway? (yes or no) Can't execute macro while defining onecolor,background-color,font-family,font-style,font-weight,font-size,text-decoration/usr/local/share/qe:/usr/local/lib/qe:/usr/share/qe:/usr/lib/qeNo suitable display found, exiting Could not initialize display '%s', exiting usage: qe [-%s [filename...] : %s %s:%d: unknown command '%s' %s:%d: string expected %s:%d: '%c' expected config*yank*%s: ,*Help*ERROR: cursor not foundDescribe key briefly:Hello, how are you ?Wrote %sCould not write %sCould not insert file '%s'Could not load '%s'Error while reloading '%s'*scratch*yes%s mode bindings Global bindings*completion*Already editing in minibuffer*minibuf*(No changes need to be saved)fileWrite file: (New file)Could not open '%s'Not defining kbd macroKeyboard macro definedAlready defining kbd macroDefining kbd macro...Replaced %d occurrencesQuery replace %s with %s: Failing hex word case-insensitive case-sensitive I-search backwardQuit%6d ^%c\U%08x\u%04xfixed,serif,sansInvalid qemacs fontUnknown style '%s'Unknown propertyitalicnormalboldinheritnoneunderline%c%c:%c%c %-20s (%s Ovwrt InteractiveL%d--C%d--%sLTRRTL--%d%%Unknown charset '%s'*tmp*(default ) %s runs the command %sInvalid Number-modeHOME/.qecommandcharsetstylelessffplayArgument expected -- %s Unknown option -- %s 0.3.1QEmacs %s - Press F1 for helptextmode-lineminibufstatuscss-defaulthighlightselectioncommentpreprocessstringkeywordfunctionvariabletypetagcssshow helputf-87bitISO-8859-1iso-ir-100latin1l1819utf8us-ascii7-bitiso-ir-6ANSI_X3.4646 <%d>*log <%s>*No futher undo informationUndo!rawinput'%s' not foundunicodeseriftimesarialhelveticafixedmonospacecourierrgb(rgba(M-%sC-%cF%d/C-leftC-rightC-upC-downC-homeC-endC-_C-spaceC-\backspaceinsertdeletepriornextSPCRETESCS-TABblackgreensilverlimegrayolivewhiteyellowmaroonnavybluepurpletealfuchsiaaquacyanmagentatransparent28>EJOU[bi{nszascii|hexdecrease-widthincrease-widthtoggle-hex%08x 0x%x--0x%xdecrease-widthvincrease-widthvset-widthi{Width: }goto-bytei{Goto byte: }toggle-hex[%d;%dH[;%d;%dm[%d;%dHvt100unihex cpp(:::::::::::::::::::::::g:::z::::::::::::::::::::c-indent-commandc-indent-regionc-electric-semi&commavc-electric-colonvc-electric-obracevc-electric-cbracev|auto|break|case|const|continue|do|else|enum|extern|for|goto|if|register|return|static|struct|switch|typedef|union|volatile|while||char|double|float|int|long|unsigned|short|signed|void|var|latexaborted/bin/sh-c*LaTeX output*%s command: %s: No match"``''AmSTeXPDFLaTeXPDFTeXChecklacheck %sBibTeXbibtex %sThumbPDFthumbpdf %sViewxdvi %s.dvi -paper a4Printdvips %s -PlpFiledvips %s.dvi -o %s.pstex-insert-quoteTeX-command-masters{Command: (default LaTeX) }[latex]|latex|amstex '\nonstopmode\input %s'pdflatex '\nonstopmode\input{%s}'pdftex '\nonstopmode\input %s'latex --src-specials '\nonstopmode\input{%s}'xml%9s%c%4d%4d-> /..dired-toggle_selectiondired-selectdired-parentdelete-windowvdired