使用C语言连接汇编语言(x86)例程

时间:2014-09-19 22:24:29

标签: c assembly x86 tasm

当我尝试从C程序调用汇编语言函数(x86)时,我遇到了一些问题。

我的汇编代码如下:

.model small
.code 
.stack 100h
public _putchar
;---------------------
;Putchar proc
;---------------------
    _putchar proc 
        push bp
        mov bp,sp
        mov dl,[bp+4]
        mov ah,2
        int 21h
        pop bp
        ret
    _putchar endp
end

然后,我从C调用此过程如下:

extern void putchar(char x);

int main(void)
{
    putchar('x');
    return 0;
}

要编译和链接,我使用以下命令行(按顺序)

tcc -c -ms pchar.c
tasm putchar.asm
tlink pchar putchar, pchar 

到目前为止,我们从putchar.asm获取了.obj,并从链接这两个文件获得了.exe文件。

我还应该提到我们(在课堂上)使用turbo汇编程序版本2.01 (tasm)和turbo链接版本2.0 (tlink)和Turbo C版本2.01 (tcc)

问题出现在这里,当我运行.exe文件时,我得到输出'x'应该是, 但它被困在那里,它没有结束。

我要感谢任何帮助,提前谢谢。

2 个答案:

答案 0 :(得分:1)

我想说,也许ret错了,你可能需要一种不同类型的回报。

如果我正确的话,可能也会从堆栈中删除参数,pascal惯例。它会是这样的:

ret 4

注意:由于您是16位,因此可能是ret 2而不是ret 4。它取决于all指令之前使用的推送指令。

否则,可以通过putchar更改__cdecl的声明。

extern __cdecl void putchar(char x);

请注意,在调试器中,您将看到堆栈是否在返回时被关注(即add sp, 4到"输出"输入参数 - 因为您是16位,它可能是2而不是4。)

我仍然对您使用bp+4而非bp+8感到惊讶。你是16位,哇!

有关calling conventions的更多信息。


旁注:

您可能希望避免使用名为putchar()的函数,因为它是在标准库中定义的,尽管在您的情况下您肯定不会受到该问题的影响。

答案 1 :(得分:1)

我观察到的两种可能性是调用例程可能正在使用AXDX

我非常怀疑这会有所帮助,但是在例行程序之前和之后尝试推动和弹出它们。

使用debug确认或反驳此信息。在调用例程之前放置一个断点,然后跳过它(而不是它)看看编译器的代码是否想要在调用ASM子例程之后使用AXDX

哦,我同意Alexis Wilke,改名。