NASM jmp winkiness

时间:2012-05-29 10:27:40

标签: macos nasm i386

我正在写一个Forth内部解释器并且陷入应该是最简单的位。在Mac上使用NASM(男子气概)

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

1 个答案:

答案 0 :(得分:0)

首先,在至少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偏移量。