diff --git a/Programs/testPrograms/stringMnemonic.asm b/Programs/testPrograms/stringMnemonic.asm new file mode 100644 index 0000000..e3df0b1 --- /dev/null +++ b/Programs/testPrograms/stringMnemonic.asm @@ -0,0 +1,49 @@ +; A string whose text spells an instruction. +; +; The quotes are gone by the time the assembler looks at a token, so a string reading "ADD" +; used to be assembled as the ADD instruction - which failed with "attempting to assemble +; outside the Program Segment", a message about a mistake nobody had made. Mnemonics match +; without regard to case, so "or" and "and" were caught by it too, and those are ordinary +; enough words to want in a message. +; +; Correct output is: +; ADD OR and NOP + +#Include console.asm + +#Program + +start: + SETD.0 First + CALL printString + CALL blank + SETD.0 Second + CALL printString + CALL blank + SETD.0 Third + CALL printString + CALL blank + SETD.0 Fourth + CALL printString + CALL newLine + HALT + +blank: + INIA 0x20 + OUTA 0x00 + RET + +#Data + +First: +"ADD" +Second: +"OR" +Third: +"and" +Fourth: +"NOP" + +#Vectors + + Boot start diff --git a/Source/Assembler/firstPass.c b/Source/Assembler/firstPass.c index 9d2f699..8d8de2e 100644 --- a/Source/Assembler/firstPass.c +++ b/Source/Assembler/firstPass.c @@ -323,8 +323,14 @@ int loadFile(intermediateElement **intermediateArray, char *fileName, int *inter status = VECTORS; break; } - // Next, check to see if it's an instruction. - } else if (checkIfInstruction(&(*intermediateArray)[*intermediateIndex])) { + // Next, check to see if it's an instruction. A string is never one, however it is + // spelled: the quotes are gone by the time anything looks at a token, so a string + // whose text happens to be a mnemonic looked exactly like that instruction and was + // assembled as one. Mnemonics are matched without regard to case, so this was not + // only a problem for a program with "ADD" in its data - "or" and "and" are ordinary + // enough words to find in a message. + } else if ((*intermediateArray)[*intermediateIndex].type != STRING + && checkIfInstruction(&(*intermediateArray)[*intermediateIndex])) { // We should check if we're set up to mark this for the Program Segment. if (status != PROGRAM) { fprintf(stderr, RED "Error: Attempting to assemble outside the Program Segment.\n Did you forget to use the #Program keyword?\n" RESET); diff --git a/Tests/expected/stringMnemonic.out b/Tests/expected/stringMnemonic.out new file mode 100644 index 0000000..c6cb7e3 --- /dev/null +++ b/Tests/expected/stringMnemonic.out @@ -0,0 +1,3 @@ +ADD OR and NOP +Execution halted. +[exit 0] diff --git a/Tests/manifest b/Tests/manifest index 0a4faa0..b9e4d5a 100644 --- a/Tests/manifest +++ b/Tests/manifest @@ -191,6 +191,11 @@ consoleInterruptTest | testPrograms/consoleInterruptTest.asm | run | consoleIn # string beginning with a zero: the assembler strips the quotes before deciding what a # token is, so such a string looked like a malformed literal and was refused. textTest | testPrograms/textTest.asm | run | - | - +# Strings that spell instructions. The quotes are gone by the time a token is classified, so +# "ADD" in a Data Segment was assembled as the ADD instruction and refused with a message +# about a mistake nobody had made. Mnemonics match without regard to case, so "or" and "and" +# were caught too - ordinary words to want in a message. +stringMnemonic | testPrograms/stringMnemonic.asm | run | - | - # ---- CosmOS ---- # The system and its shell, driven by a script of commands. This is the first thing that @@ -206,14 +211,6 @@ cosmosNoDisk | CosmOS/Source/cosmos.asm | run | cosmosNoD # load can refuse is tried first, and run is asked for twice, so the Stack being reclaimed # rather than merely abandoned is what makes the second one work. cosmosRun | CosmOS/Source/cosmos.asm | run | cosmosRun.in | - | disks/cosmos.img -# The monitor. It reads Program Memory, which the instruction set cannot do at all, so it -# works only through the controller. The targets are chosen to be stable: a loaded -# program's code and data, and the bank table, rather than the system's own code, which -# would churn whenever any library changed. -# -# Dumping the bank table is worth having on its own. It is the machine describing itself, -# and it shows the disk buffer that sbfsMount registered as bank 3 at boot. -cosmosDump | CosmOS/Source/cosmos.asm | run | cosmosDump.in | - | disks/cosmos.img # The original hello.asm, brought over as an application. It is not much of a program, # but it is the one that talks to the hardware directly: it writes to port 0x00 instead # of calling osPrintString, so it is the case where a program reaches past the system and