diff --git a/mspdebug.man b/mspdebug.man
index a5d1652..6cbf58a 100644
--- a/mspdebug.man
+++ b/mspdebug.man
@@ -92,6 +92,11 @@ Display a brief help message and exit.
 MSPDebug can accept commands either through an interactive prompt, or
 non-interactively when specified on the command line. The supported
 commands are listed below.
+
+Commands take arguments separated by spaces. Any text string enclosed
+in double-quotation marks is considered to be a single argument, even
+if it contains space characters. Within a quoted string, the usual
+C-style backslash substitutions can be used.
 .IP "\fB=\fR \fIexpression\fR"
 Evaluate an address expression and show both its value, and the result
 when the value is looked up in reverse in the current symbol
diff --git a/parse.c b/parse.c
index 61655cb..ffb1d09 100644
--- a/parse.c
+++ b/parse.c
@@ -85,7 +85,10 @@ int is_interactive(void)
 char *get_arg(char **text)
 {
 	char *start;
+	char *rewrite;
 	char *end;
+	int qstate = 0;
+	int qval = 0;
 
 	if (!text)
 		return NULL;
@@ -97,14 +100,90 @@ char *get_arg(char **text)
 	if (!*start)
 		return NULL;
 
+	/* We've found the start of the argument. Parse it. */
 	end = start;
-	while (*end && !isspace(*end))
+	rewrite = start;
+	while (*end) {
+		switch (qstate) {
+		case 0: /* Bare */
+			if (isspace(*end))
+				goto out;
+			else if (*end == '"')
+				qstate = 1;
+			else
+				*(rewrite++) = *end;
+			break;
+
+		case 1: /* In quotes */
+			if (*end == '"')
+				qstate = 0;
+			else if (*end == '\\')
+				qstate = 2;
+			else
+				*(rewrite++) = *end;
+			break;
+
+		case 2: /* Backslash */
+			if (*end == '\\')
+				*(rewrite++) = '\\';
+			else if (*end == 'n')
+				*(rewrite++) = '\n';
+			else if (*end == 'r')
+				*(rewrite++) = '\r';
+			else if (*end == 't')
+				*(rewrite++) = '\t';
+			else if (*end >= '0' && *end <= '3') {
+				qstate = 30;
+				qval = *end - '0';
+			} else if (*end == 'x') {
+				qstate = 40;
+				qval = 0;
+			} else
+				*(rewrite++) = *end;
+
+			if (qstate == 2)
+				qstate = 1;
+			break;
+
+		case 30: /* Octal */
+		case 31:
+			if (*end >= '0' && *end <= '7')
+				qval = (qval << 3) | (*end - '0');
+
+			if (qstate == 31) {
+				*(rewrite++) = qval;
+				qstate = 1;
+			} else {
+				qstate++;
+			}
+			break;
+
+		case 40: /* Hex */
+		case 41:
+			if (isdigit(*end))
+				qval = (qval << 4) | (*end - '0');
+			else if (isupper(*end))
+				qval = (qval << 4) | (*end - 'A' + 10);
+			else if (islower(*end))
+				qval = (qval << 4) | (*end - 'a' + 10);
+
+			if (qstate == 41) {
+				*(rewrite++) = qval;
+				qstate = 1;
+			} else {
+				qstate++;
+			}
+			break;
+		}
+
+		end++;
+	}
+ out:
+	/* Leave the text pointer at the end of the next argument */
+	while (*end && isspace(*end))
 		end++;
 
-	if (*end)
-	    while (*end && isspace(*end))
-		    *(end++) = 0;
-
+	*rewrite = 0;
 	*text = end;
 	return start;
 }