colorful rat Ratfactor.com > Dave's Repos

nasmjf

A NASM assembler port of JONESFORTH
git clone http://ratfactor.com/repos/nasmjf/nasmjf.git

nasmjf/devlog/log03.txt

Download raw file: devlog/log03.txt

1 Picking up at the error discovered in the last log, 2 we need to figure out what's happening to the string 3 stored at the label 'errmsg'. 4 5 (I keep having to re-learn that GBD needs an '&' before 6 a label for it to be used as an address expression, 7 otherwise it uses the value _at_ that label. Hope I remember 8 it this time after fumbling around for a while...which is 9 not pictured here.) 10 11 The string is correct ("PARSE ERROR: ") when the program starts. 12 (Though it looks like I didn't get the newline escape right 13 in NASM because I have a literal '\n' in my string!" 14 15 Reading symbols from nasmjf... 16 (gdb) info addr errmsg 17 Symbol "errmsg" is at 0x804a315 in a file compiled without debugging. 18 (gdb) x/20c &errmsg 19 0x804a315 <errmsg>: 80 'P' 65 'A' 82 'R' 83 'S' 69 'E' 32 ' ' 69 'E' 82 'R' 20 0x804a31d: 82 'R' 79 'O' 82 'R' 58 ':' 32 ' ' 92 '\\' 110 'n' 0 '\000' 21 0x804a325: 0 '\000' 0 '\000' 0 '\000' 0 '\000' 22 23 I set a watchpoint on the label and run it. 24 25 (gdb) watch (int)errmsg 26 Watchpoint 2: (int)errmsg 27 (gdb) c 28 Continuing. 29 foo 30 31 Watchpoint 2: (int)errmsg 32 33 Old value = 1397899600 34 New value = 1392508928 35 code_INTERPRET () at nasmjf.asm:214 36 214 call _FIND ; Returns %eax = pointer to header or 0 if not found. 37 (gdb) 38 39 Okay, so I guess that means that the line _before_ 214 must 40 be the culprit. Ah, yeah. That looks likely because here's 41 how the memory is reserved: 42 43 interpret_is_lit: db 0 ; 1 means "reading a literal" 44 errmsg: db "PARSE ERROR: " 45 46 And here's the line before 214: 47 48 mov [interpret_is_lit], eax ; 0 means not a literal number (yet) 49 50 Yup, that sure makes sense! We reserved a byte for the 51 interpret_is_lit flag, but eax is a full word (4 bytes), 52 so the flag is getting set _and_ the remaining three 53 bytes clobber the string in errmsg. It's things like this that 54 make a person appreciate the safety features of higher 55 level languages. 56 57 Angway, the data size was "int" in the JonesForth GAS original. 58 So mine should be 'w' for word: 59 60 interpret_is_lit: dw 0 ; 1 means "reading a literal" 61 62 Let's try it: 63 64 (gdb) file nasmjf 65 Reading symbols from nasmjf... 66 (gdb) break 271 67 Note: breakpoints 3, 4 and 5 also set at pc 0x80490ba. 68 Breakpoint 6 at 0x80490ba: file nasmjf.asm, line 271. 69 (gdb) r 70 Starting program: /home/dave/nasmjf/nasmjf 71 foo 72 73 Breakpoint 3, code_INTERPRET.parse_error () at nasmjf.asm:271 74 271 int 80h 75 PARSE ERROR: 76 77 Yay, that's restored the PARSE ERROR string. 78 Unfortunately, it still ends in a segfault. 79 Oops! Both the errmsgnl and __NR_write labels 80 should be the addresses, not the values at the 81 addresses at lines 284 and 286. 82 83 273 mov [currkey],ecx ; the error occurred just before currkey position 84 274 mov edx,ecx 85 275 sub edx,buffer ; edx = currkey - buffer (length in buffer before currkey) 86 276 cmp edx,40 ; if > 40, then print only 40 characters 87 277 jle .print_error 88 code_INTERPRET.print_error () at nasmjf.asm:280 89 280 sub ecx,edx ; ecx = start of area to print, edx = length 90 281 mov eax,__NR_write ; write syscall 91 282 int 80h 92 284 mov ecx,[errmsgnl] ; newline 93 285 mov edx,1 ; 1 char long 94 286 mov eax,[__NR_write] ; write syscall 95 96 Program received signal SIGSEGV, Segmentation fault. 97 98 Okay, easy fix. I also noticed I stll had the operands 99 transposed on line 273. And I swapped out the double 100 quotes around the errmsgnl string literal to backquotes 101 as required by NASM for backslash escape support. 102 103 Let's see how it goes now: 104 105 Continuing. 106 foo 107 PARSE ERROR: foo 108 109 [Inferior 1 (process 2582) exited normally] 110 111 Yay! 112 113 114 115