CALL指令(语法错误),MASM

时间:2014-11-10 06:43:39

标签: assembly x86 pascal inline-assembly masm

问题: Error 5: Syntax error(在下面的代码中的评论中指出) 假设它们应该被等效指令取代,但我无法弄明白。但是为什么我要修改AFD-Pro调试器反汇编的代码?想一想,必须复制它才能替换 .PAS 代码中的模拟线。

已阅读 IA-32英特尔架构软件开发人员手册,第1卷,第6.3章"使用呼叫和RET调用程序" 但仍然没有'理解为什么CALL指向9721:0691以及为什么Turbo Pascal 7.0编译器提供 syntax error

工具: Windows 7操作系统,DosBOX 0.74,Turbo Pascal 7.0,AFD-Pro(在DosBOX中)。

.PAS 代码:

Program ASMINLINE;
Var 
    i,m:integer;
    A:array [10..20] of integer;

Begin
    m:=1;
    i:=10;

    while i<=20 do begin
        A[i]:=3*i;
        m:=m+A[i];
        if m>100 then
            A[i]:=2*i;
            inc(i);
    end;

    ASM
    {for i:=10 to 20 do}
        MOV     i,000Ah
        JMP     @20
    @10:
        INC   i

    {write(A[i]:4);}
    @20:
        MOV     DI, 016Ch
        PUSH    DS
        PUSH    DI
        MOV     DI,i
        SHL     DI,1
        MOV     AX,[0042+DI]
        CWD
        PUSH    DX
        PUSH    AX
        MOV     AX,0004h
        PUSH    AX
        CALL    9721:0691
        {           ^ Error 5: Syntax error. }
        CALL    9721:05FE
        CALL    9721:0291
        CMP     i,0014h
        JNZ     @10
    END; {ASM}

    writeln;
End.

以下是我在 .PAS 文件中包含的 .PRN 文件的一部分。 我用AFD-Pro v1.0(AdTec GmbH,1987; Processor:80286)调试器得到它:

for i:=10 to 20 do
9716:0061 C70652000A00   MOV    [0052],000A
9716:0067 EB04           JMP    006D
9716:0069 FF065200       INC    W/[0052]

        write(A[i]:4);
9716:006D BF6C01         MOV    DI,016C
9716:0070 1E             PUSH   DS
9716:0071 57             PUSH   DI
9716:0072 8B3E5200       MOV    DI,[0052]
9716:0076 D1E7           SHL    DI,1
9716:0078 8B854200       MOV    AX,[0042+DI]
9716:007C 99             CWD
9716:007D 52             PUSH   DX
9716:007E 50             PUSH   AX
9716:007F B80400         MOV    AX,0004
9716:0082 50             PUSH   AX
9716:0083 9A91062197     CALL   9721:0691
9716:0088 9AFE052197     CALL   9721:05FE
9716:008D 9A91022197     CALL   9721:0291
9716:0092 833E520014     CMP    [0052],0014
9716:0097 75D0           JNZ    0069

2 个答案:

答案 0 :(得分:0)

那个时代的许多汇编者都不喜欢绝对的段地址。他们更喜欢使用符号段。

它会被写成这样的东西(从我的头顶开始,自从我编写旧的x86汇编程序以来已经很长时间了):

b123   segment  abs 0123H      ; declare segment at an absolute location

$  equ  4321h                  ; declare something at offset 0x4321

some_proc    proc   far
; body of function goes here
some_proc    endp

b123   ends                    ; end working in this segment


   .code

    call some_proc             ; should generate call to 123h:4321h

答案 1 :(得分:0)

您可以通过用相应的字节和字值替换memnonic(“CALL ...”)来解决问题。

替换

CALL    9721:0691

通过

DB 9Ah            { CALL FAR }
DW 0691h, 9721h   { 9721:0691 }

不要忘记h - 后缀!