我正在写一个Forth内部解释器,并且被本应该是最简单的部分卡住了。在Mac上使用NASM (macho)
msg db "k thx bye",0xA ; string with carriage return
len equ $ - msg ; string length in bytes
xt_test:
dw xt_bye ; <- SI Starts Here
dw 0
db 3,'bye'
xt_bye dw $+2 ; <- Should point to...
push dword len ; <-- code here
push dword msg ; <--- but it never gets here
push dword 1
mov eax, 0x4 ; print the msg
int 80h
add esp, 12
push dword 0
mov eax, 0x1 ; exit(0)
int 80h
_main:
mov si,xt_test ; si points to the first xt
lodsw ; ax now points to the CFA of the first word, si to the next word
mov di,ax
jmp [di] ; jmp to address in CFA (Here's the segfault)当它运行时,我得到了分段错误: 11。作为测试,我可以将_main更改为
_main:
mov di,xt_bye+2
jmp di而且它是有效的
编辑-这是我尝试做的最简单的形式,因为我认为有一些转移注意力的问题:)
a dw b
b dw c
c jmp _my_actual_code
_main:
mov si,a
lodsw
mov di,ax
jmp [di]编辑-在六进制转储之后,我可以看到上面b中的值实际上比编译标签c的地址高0x1000。C位于0x00000f43,但b包含0x1f40
发布于 2012-05-29 18:37:38
首先,在至少32位的现代x86机器上使用'si‘和'di’16位寄存器看起来非常危险。
尝试使用“esi”和“edi”。当'xt_bye‘不大于2^16时,您可能很幸运地避免了一些崩溃。
另一件事:在xt_bye的末尾没有“RET”。
另一个:请参阅此链接问题Help with Assembly. Segmentation fault when compiling samples on Mac OS X
看起来你改变了ESP寄存器太多了,它变成了16个字节的未对齐。因此就发生了崩溃。
再来一次:
jmp [di]可能无法加载正确的地址,因为未使用DS/ES寄存器,因此偏移量为0x1000。
https://stackoverflow.com/questions/10797319
复制相似问题