8086 Assembley - вызовите Printf в модели большой - PullRequest
0 голосов
/ 21 марта 2012

Я пытаюсь использовать printf в моем ассемблерном коде в большой модели, и я получаю переполнение исправления, что мне нужно изменить в этом коде, чтобы он работал?

.MODEL LARGE
.STACK 100h
.DATA
int     DW "%d"
.CODE
.386

extrn   _printf:far
PUBLIC _stack_protection
_stack_protection PROC FAR
push    bp          
mov bp,sp           
push    es
mov     ax,10
push    ax
push    word ptr int
call    _printf
add sp,4
pop es  
pop bp          
ret 
_stack_protection ENDP
    END

1 Ответ

1 голос
/ 30 марта 2012

Вы должны изменить это:

int     DW "%d"

к этому:

_int     DB "%d",0

Поскольку printf() ожидает нормальных C-строк с нулевым символом в конце, потому что строки C состоят из байтов, а не слов, и поскольку int, скорее всего, является зарезервированным словом (по крайней мере, в TASM).

Вы также должны изменить это:

push    word ptr int
...
add sp,4

к этому:

push    seg _int
push    offset _int
...
add sp,6

Поскольку в модели с большой памятью все указатели расположены далеко, то есть состоят из сегмента и смещения.

Итак, это то, чем я заканчиваю ...

ASM-файл:

; file: larg.asm
; how to assemble: tasm.exe /ml larg.asm
.MODEL LARGE

;.STACK 100h ; unnecessary and too small anyway,
; let the C compiler take care of it

DATA segment word public 'DATA' ; make sure class='DATA' (default)
;int     DW "%d" ; 'int' is a reserved word,
; C strings must consist of bytes/chars and end with byte 0
_int    DB "%d", 0
DATA ends

extrn   _printf:far ; for some reason this must be
; outside of the code segment

CODE segment byte public 'CODE' USE16 ; make sure it's
; 16-bit code, class='CODE' (default)
assume cs:CODE
.386

PUBLIC _stack_protection
_stack_protection PROC FAR
push    bp
mov     bp,sp
push    es
mov     ax,10
push    ax
;push    word ptr int ; must be the far address of '_int'
; because in the 'large' memory model all pointers are 'far'
push    seg _int
push    offset _int
call    _printf
;add sp,4 ; must account for the far address size on stack
add     sp,6
pop     es
pop     bp
ret
_stack_protection ENDP
CODE ends

    END

C файл:

// file: large.c
// how to compile: tcc.exe -mlarge large.c larg.obj

#include <stdio.h>

extern void stack_protection(void);

int main(void)
{
  stack_protection();
  printf("\n");
  return 0;
}

Затем я компилирую программу (с Turbo C ++ 1.01 и TASM 3.2):

tasm.exe /ml larg.asm
tcc.exe -mlarge large.c larg.obj

И запустить его:

c:\large.exe
10
...