2014-11-10 5 views
0

인한 문제 :Error 5: Syntax error (아래 코드에 코멘트에서 지적)한다고 가정 , 그들은 동등한 명령에 의해 대체되어야하지만 난 그것을 알아낼 수 없습니다. 하지만 AFD-Pro 디버거가 해체 한 코드를 수정해야하는 이유는 무엇입니까? 그것은 단지 .PAS 코드의 아날로그 라인을 대체하기 위해 복사해야합니다.CALL 명령 (구문 오류), MASM

는 "전화 및 RET를 사용하여 프로 시저 호출"장 6.3 IA-32 인텔 아키텍처 소프트웨어 개발자 설명서 1 권을 읽고하지만 아직도 내가 왜 CALL9721:0691에 왜 터보 파스칼 7.0 컴파일러가 제공 이해하지 않는다 syntax error.

TOOLS : Windows 7 OS, 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-프로 v1.0을 사용하여 그것을 가지고 (ADTEC GmbH를, 1987; 프로세서 : 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 
+0

전화 걸기 call dword ptr ....? –

+0

@MarcovandeVoort, 무슨 뜻인지 설명해 주시겠습니까? – yulian

+0

세그먼트 : offset에 대한 호출이 FAR 호출이고, 단지 오프셋에 대한 호출 (CS :에 대한 상대)이 거의 있습니다. 어떤 어셈블러는 그것을 위해 니모닉에서 추가 힌트를 필요로합니다 (callf, call far etc). –

답변

0

많은 절대 세그먼트 주소를 좋아하지 않았다. 그들은 상징적 인 부분을 사용하는 것을 선호했다.

이 (내 머리 위로 떨어져 그리고 내가 옛날 86 어셈블러를 작성한 이후 오랜 시간이있다) 같은 것을 기록 할 것 : 당신은 memnonic를 교체하여 문제를 해결할 수

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 
+0

코드 세그먼트에만 액세스 할 수있는 경우이 솔루션을 구현하는 방법은 무엇입니까? 내가 알기로는, .code는 코드 세그먼트의 시작이지만, 어떤 세그먼트에서 (b123)을 써야 하는가? – yulian

+0

@YulianKhlevnoy :'some_proc'이 세그먼트'b123'에 있다고 선언되었으므로 호출 명령은'0123h : 4321h'에 대한 'far'참조가됩니다. – wallyk

0

("CALL ...")를 대응하는 바이트 및 워드 값으로 변환합니다.

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

에 의해

CALL 9721:0691 

h -suffix 잊지 마세요 교체!

+0

나는 그것을 * 데이터 세그먼트 *에 써야합니다. 인라인을 사용하려고 할 때 프로그램 중간에서 어떻게 데이터 세그먼트에 액세스 할 수 있습니까? – yulian

+0

'DB 9Ah'과'DW 0691h, 9721h'로'CALL 9721 : 0691'을 바꾸면 "16 비트 MS-DOS 서브 시스템 | 터보 파스칼 | NTVDM CPU에 잘못된 명령이 생겼습니다. | CS : 9721 IP : 5efa OP : 64 63 61 72 64' "프로그램이 현금화됩니다. 추신 비록 처음에는 그렇게 쉽지는 않지만 어셈블러에게는 아주 익숙하지만 그것을 배우기를 원합니다. – yulian

+0

@YulianKhlevnoy : 아니요! "대체"는 실제로 "대체"를 의미합니다. "CALL ..."을 사용하여 한 줄의 ** 대신 ** DB ...와 "DW ..."** 두 줄을 씁니다. 하지만 나는 행동 감각에 의심이갑니다. 절대 주소는 다음 번 컴파일시 ** 및 ** 다음 실행시 변경 될 수 있습니다. – rkhb