c - 额外插入 OpenWatcom 内联组装

标签 c dos x86-16 inline-assembly watcom

我正在使用 OpenWatcom V2 wcc 编译此 C 源代码:

/* Writes a '\0'-terminated string to the file descriptor. */
static void fdputs(int fd, const char *s);
#pragma aux fdputs = \
"push si" \
"mov cx, -1" \
"repz scasb" \
"neg cx" \
"inc cx"  /* now cx is the number of bytes to write */ \
"pop dx"  /* now dx points to the buffer (s argument) */ \
"mov ah, 0x40" /* WRITE */ \
"int 0x21" \
parm [ bx si ] \
modify [ ax cx dx si ];  /* Also modifies cf */

int myfunc(void) {
  fdputs(1, "Hello!");
  return 0;
}

在对 wcc 生成的 .obj 文件进行反汇编时,6 个 push 和 5 个 pop 并不平衡。 (代码在运行时会因此崩溃。)

$ wcc -bt=dos -ms -s -os -W -w4 -wx -we -wcd=202 -0 -fr -fo=t.obj t.c
$ wdis -a -fi -i=@ t.obj
.387
                PUBLIC  myfunc_
                EXTRN   _small_code_:BYTE
DGROUP          GROUP   CONST,CONST2,_DATA
_TEXT           SEGMENT BYTE PUBLIC USE16 'CODE'
                ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
myfunc_:
        push            bx
        push            cx
        push            dx
        push            si
        mov             ax,offset DGROUP:@$1
        push            ax
        mov             bx,1
        xor             si,si
        push            si
        mov             cx,0ffffH
        repe scasb
        neg             cx
        inc             cx
        pop             dx
        mov             ah,40H
        int             21H
        xor             ax,ax
        pop             si
        pop             dx
        pop             cx
        pop             bx
        ret
_TEXT           ENDS
CONST           SEGMENT WORD PUBLIC USE16 'DATA'
@$1:
    DB  48H, 65H, 6cH, 6cH, 6fH, 21H, 0

CONST           ENDS
CONST2          SEGMENT WORD PUBLIC USE16 'DATA'
CONST2          ENDS
_DATA           SEGMENT WORD PUBLIC USE16 'DATA'
_DATA           ENDS
                END

我是否正确使用了 wcc 内联汇编?这可能是 wcc 中的错误吗?

最佳答案

我相信这是 OpenWatcom C/C++ 的一个错误,因为我过去观察到过这种行为。为了解决这个问题,我在它们自己的 [] 之间分别列出了每个参数。尝试修改:

parm [ bx si ] \

成为:

parm [ bx ] [ si ] \

生成的代码应如下所示:

.387
                PUBLIC  myfunc_
                EXTRN   _small_code_:BYTE
DGROUP          GROUP   CONST,CONST2,_DATA
_TEXT           SEGMENT BYTE PUBLIC USE16 'CODE'
                ASSUME CS:_TEXT, DS:DGROUP, SS:DGROUP
myfunc_:
        push            bx
        push            cx
        push            dx
        push            si
        mov             si,offset DGROUP:@$1
        mov             bx,1
        push            si
        mov             cx,0ffffH
        repe scasb
        neg             cx
        inc             cx
        pop             dx
        mov             ah,40H
        int             21H
        xor             ax,ax
        pop             si
        pop             dx
        pop             cx
        pop             bx
        ret
_TEXT           ENDS
CONST           SEGMENT WORD PUBLIC USE16 'DATA'
@$1:
    DB  48H, 65H, 6cH, 6cH, 6fH, 21H, 0

CONST           ENDS
CONST2          SEGMENT WORD PUBLIC USE16 'DATA'
CONST2          ENDS
_DATA           SEGMENT WORD PUBLIC USE16 'DATA'
_DATA           ENDS
                END

使用AX寄存器来传输const char *s的地址以及额外的push ax被删除没有与之关联的相应 pop

关于c - 额外插入 OpenWatcom 内联组装,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62866916/

相关文章:

c - 为什么cgo的性能这么慢?我的测试代码有问题吗?

c - 父进程终止子进程的输出是什么?

assembly - 如何在 DOSBox 中使用汇编程序消除字符串中的空格和标点符号?

java - 将 jar 文件添加到类路径

assembly - 什么是段以及如何在 8086 模式下对其进行寻址?

c - 范围通常如何影响嵌套函数的使用?

创建 16 位应用程序?

assembly - 在手动编码的远调用后定义出现在调试中的字节

assembly - INT 13h 无法读取超出特定扇区的数据

c - 可能的输出是什么?