2

我一直在玩 DOS 实模式汇编,现在我想在 C 程序中使用一些例程。我正在使用 Turbo C 2.01 和 TASM 3.0。但是,我无法修改通过地址传递的变量,请参阅下面的 _setval 例程。我不需要/想要内联汇编。一个简单的例子:

foo.c

#include <stdio.h>
extern void setval(int *x, int *y);
extern int sum(int x, int y);
int main()
{
    int result, a, b;
    result = a = b = 0;
    setval(&a, &b);
    result = a + b;
    printf("a+b=%i, a=%i, b=%i\n", result, a, b);
    result = 0;
    a = 42;
    b = 19;
    result = sum(a, b);
    printf("a+b=%i, a=%i, b=%i\n", result, a, b);
    return 0;
}

脚丫子.asm

public _setval
public _sum
.model small
.stack
.data
.code
_setval proc near
push bp
mov bp, sp
mov word ptr [bp+4], 42
mov word ptr [bp+6], 19
pop bp
ret
endp
_sum proc near
push bp
mov bp, sp
mov ax, word ptr [bp+4]
add ax, word ptr [bp+6]
pop bp
ret
endp
end

我这样编译它:

tcc -c -ms foo.c
tasm /ml foortn.asm
tcc foo.obj foortn.obj

结果是:

a+b=0, a=0, b=0
a+b=61, a=42, b=19

我显然错过了一些东西,但是什么?

汉斯、马克和比尔,非常感谢您的及时和有益的答复。

4

4 回答 4

4

您当前的代码正在覆盖传递的指针。您需要检索指针并通过它进行写入。像这样的东西:

mov ax, word ptr [bp+4]
mov word ptr [ax], 42

首先用 C 语言编写此代码,然后查看它生成的汇编代码以使其正确。

于 2010-10-03T15:48:09.480 回答
1

尝试更换:

mov word ptr [bp+4], 42
mov word ptr [bp+6], 19

mov bx, word ptr [bp+4]
mov [bx], 42
mov bx, word ptr [bp+6]
mov [bx], 19
于 2010-10-03T15:44:48.643 回答
0

这个:

mov word ptr [bp+4], 42
mov word ptr [bp+6], 19

正在写入堆栈,而不是堆栈上的地址。您需要读取堆栈上的地址,然后改为写入它们:

mov bx,[bp+4]  ; get the address of (a)
mov [bx],42    ; Write to that address
mov bx,[bp+6]  ; (b)
mov [bx],19    ; write
于 2010-10-03T16:05:32.317 回答
-1

我不知道汇编程序...但是按值C传递所有内容。

sum[bp+4] 中是 42(或 19);在[bp+4] 中是0xDEADBEEF 0xDECAFBAD (或其他)addsetval

于 2010-10-03T15:29:22.860 回答