额外推动 OpenWatcom 内联汇编
Extra push in OpenWatcom inline assembly
我正在使用 OpenWatcom V2 编译此 C 源代码wcc
:
/* Writes a '[=10=]'-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
es 和 5 pop
s 不平衡。 (代码在 运行 时因此崩溃。)
$ 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:@
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'
@:
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:@
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'
@:
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
与之关联。
我正在使用 OpenWatcom V2 编译此 C 源代码wcc
:
/* Writes a '[=10=]'-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
es 和 5 pop
s 不平衡。 (代码在 运行 时因此崩溃。)
$ 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:@
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'
@:
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:@
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'
@:
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
与之关联。