5

这是我正在处理的程序的测试过程,我通过堆栈传递了一些参数,其中一个是指针。当我尝试更改取消引用指针的值时,变量不会更新。

_testProc proc
    push bp                             ;Save base pointer to stack
    mov bp, sp                          ;Set new base pointer
    sub sp, 4                           ;Allocate stack space for locals
    pusha                               ;Save registers to stack

    mov di, [bp + 08]                   ;Parm 3 - ptr to variable

    mov word ptr [di], 10   ; <---- Doesn't work. di contains an address, 
                            ;       but what it points at doesn't get updated

    popa                                ;Restore registers from stack
    mov sp, bp                          ;Remove local vars by restoring sp
    pop bp                              ;Restore base pointer from stack
    ret 6                               ;Return and also clean up parms on stack
_testProc endp
4

2 回答 2

3

8086通过段寄存器和索引寄存器的内容组合产生和寻址;我将其显示为 [SR,IR]。

您通过寄存器 di 的更新正在更新 [DS,DI] 定义的位置;没有任何特殊前缀的 mov 指令默认使用 DS 寄存器。如果您将地址 DI 作为某个其他段(ES?SS?)的偏移量,那么您实际上是在组合错误的寄存器来访问您想要的地址。

您的错误在于不清楚将“指针”传递给您的例程的约定是什么。您所定义的假设与 DS 有相对偏移。

于 2012-12-02T07:27:46.483 回答
2

您能做的最好的事情就是尽快放弃 16 位分段代码!:)

如果做不到这一点,就会有“远数据”和指向它的“远指针”。你的“proc”没有说它是近还是远 - 我假设近(或者 Parm3 可能不是你认为它在堆栈上的位置......因为远返回地址是 4 个字节)。如果您打算更改的变量在堆栈上,那么您会遇到一些更复杂的情况。mov word ptr ss:[di], 10至少。如果您需要处理局部变量或静态变量,我认为您将需要一个远指针(4 个字节、段和偏移量)来找到它。

我首先想到的是,您说您正在尝试更改取消引用指针的值,而不是“取消引用”它(据我所知)。mov di, [di]在您从堆栈中获取值后尝试。无论如何,很容易尝试。:)

如果一切都失败了,请向我们展示调用代码。(并尽快进入 32 位代码!)

于 2012-12-02T11:29:25.610 回答