Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
汇编语言(x86)例程与C语言的接口_C_Assembly_X86_Tasm - Fatal编程技术网

汇编语言(x86)例程与C语言的接口

汇编语言(x86)例程与C语言的接口,c,assembly,x86,tasm,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

当我试图从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;
}
为了编译和链接,我使用以下命令行(按顺序)

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

我还应该提到,我们(在课堂上)使用的是turbo assembler版本2.01(tasm)、turbo link版本2.0(tlink)和turbo C版本2.01(tcc)

问题来了,当我运行.exe文件时,我得到了输出“x”,正如它应该的那样, 但是它被卡在那里,它没有结束


我将感谢任何帮助,提前谢谢

我想说,也许
ret
是错误的,您可能需要不同类型的退货

如果我是正确的,可能还有一个从堆栈中删除参数的方法,pascal约定。应该是这样的:

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

否则,可以使用
\uuu cdecl
更改
putchar
的声明

extern __cdecl void putchar(char x);
请注意,在调试器中,您将看到堆栈是否在返回时得到处理(即,
add sp,4
以“丢失”输入参数——因为您在16位中,它可能是2而不是4。)

我仍然很惊讶你使用了
bp+4
,而不是
bp+8
。你是在16位,哇

更多关于


旁注:


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

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

我严重怀疑这是否会有帮助,但试着在例行训练前后推动和弹出这些

通过调试确认或反驳这一点。在调用例程之前放置一个断点,并在调用ASM子例程之后跳过它(而不是进入它),查看编译器的代码是否要使用
AX
DX


哦,我同意亚历克西斯·威尔克的观点,换个名字。

看不出任何明显的问题。使用调试器查看函数是否返回。另外,告诉你的学校,使用这些过时的东西会让学习变得更加困难,而没有任何好处。啊!说得好。可能需要保存DX。我会很惊讶AX不会成为返回登记簿。@Alexiswillke它被宣布为无效,谁能预测出制造那些比我们这些愚蠢的凡人好得多的编译器的专家,你知道吗?
extern __cdecl void putchar(char x);