【问题标题】:NASM jmp wonkinessNASM jmp 摇晃
【发布时间】:2012-05-29 10:27:39
【问题描述】:

我正在编写一个 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)

运行时出现 Segmentation Fault: 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]

EDIT - 对二进制文件进行十六进制转储后,我可以看到上面 b 中的值实际上比标签 c 编译的地址高 0x1000。 c 在 0x00000f43,但 b 包含 0x1f40

【问题讨论】:

  • 也许你应该发布完整的源代码? msg,_syscall(只是“int 0x80”吗?)
  • 对 - _syscall 只是 int 80h,唯一缺少的是 msg 和 len,我会去修复 :)
  • 看起来这与段寄存器有关。 0x1000 偏移量可能来自 DS=0x100 之类的。抱歉,我只有一台旧的 PowerPC G5 mac,所以我无法准确测试您的 x86 asm :)
  • 非常感谢您对此提供的帮助,Viktor - 它可能假定 DS 而不是 CS,这是有道理的 - 我会试一试并告诉您。
  • 当然,所有这些漂亮的装配难题让我想起了很多过去 :) 很高兴能提供帮助 :)

标签: macos nasm i386


【解决方案1】:

首先,在至少 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 reg,因此偏移量为 0x1000。

【讨论】:

  • 对 - 恐怕我为了在此处发布而过度简化了 - 它在 xt_bye 的例程结束时退出,因此没有必要返回(而且,它没有被调用) - 另外,我使用 esi 和 edi 寄存器得到了相同的结果,但最终目标是让它作为引导扇区在实模式下运行
  • 我猜这是一个无返回程序,所以我没有把它作为主要来源。 esi/edi 也可能不是问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多