【问题标题】:Using assembly routines with C on DOS在 DOS 上使用 C 汇编程序
【发布时间】:2010-10-03 15:20:14
【问题描述】:

我一直在玩 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;
}

foortn.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

我显然错过了什么,但是什么?

Hans、Mark 和 Bill,非常感谢您的及时和有益的回复。

【问题讨论】:

    标签: c assembly dos turbo-c


    【解决方案1】:

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

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

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

    【讨论】:

    • 哦...我明白了。确实,您是对的,指针被覆盖了。非常感谢,我完全忽略了这一点。我会找一个像样的 DOS 调试器,debug.com 让我无语。
    • 我很确定 Turbo C 的免费下载包含一个调试器。 edn.embarcadero.com/article/20841
    【解决方案2】:

    尝试替换:

    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
    

    【讨论】:

      【解决方案3】:

      这个:

      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
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 你的回答对我来说没有意义。请注意,OP 调用 setval(&amp;a, &amp;b); 通过指针传递,sum(a, b); 通过值传递。
        • 是的,然后他在 (word ptr [bp+4]) 汇编器中以完全相同的方式使用 [bp+4]。这就是我觉得奇怪的地方,甚至不知道汇编程序:我认为它们需要以某种方式有所不同(而且,不,我不知道有多么不同)
        • 我指的是 _setval,而不是 _sum
        猜你喜欢
        • 1970-01-01
        • 2011-12-13
        • 2017-10-06
        • 2011-10-14
        • 1970-01-01
        • 2011-05-21
        • 2011-05-23
        • 2021-11-11
        • 1970-01-01
        相关资源
        最近更新 更多