在 DOS 上使用 C 汇编例程

发布于 2024-09-25 21:37:50 字数 1109 浏览 6 评论 0原文

我已经使用 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

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

汉斯、马克和比尔,非常感谢你们及时而有用的回复。

I've been playing with DOS real mode assembly for a while and now I want to utilize some routines in a C program. I'm using Turbo C 2.01 and TASM 3.0. I'm however unable to modify a variable passed by address, see the _setval routine below. I don't need/want inline assembly. A simple example:

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

I compile it like this:

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

The result is:

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

I'm obviously missing something, but what?

Hans, Mark and Bill, thank you very much for your prompt and helpful responses.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

虫児飞 2024-10-02 21:37:50

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

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

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

Your current code is overwriting the passed pointer. You need to retrieve the pointer and write through it. Something like this:

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

Write this code in C first and look at the assembly code that it generates to get this right.

兔小萌 2024-10-02 21:37:50

尝试替换:

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

Try replacing:

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

with

mov bx, word ptr [bp+4]
mov [bx], 42
mov bx, word ptr [bp+6]
mov [bx], 19
-小熊_ 2024-10-02 21:37:50

这是:

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

This:

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

is writing to the stack, not the addresses on the stack. You'll need to read the addresses on the stack, then write to them instead:

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
贱人配狗天长地久 2024-10-02 21:37:50

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

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

I don't know assembler ... but C passes everything by value.

In sum [bp+4] is 42 (or 19); in addsetval [bp+4] is 0xDEADBEEF 0xDECAFBAD (or whatever)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文