2012-03-20 5 views
0

私のassembleyコードでprintfを使ってみようとしていますが、fixupオーバーフローが発生しました。このコードを変更する必要がありますか? printf()が通常期待し8086アセンブリー - printf in largeモデル

_int  DB "%d",0 

ので、NULで終了するC文字列は、Cの文字列はバイトではなく、言葉で構成されているので:これまで

int  DW "%d" 

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

なぜ人々は16ビットアセンブリコードを書いているのですか?あなたのprintfは16ビットですか? –

+0

おそらく、FAR _printfを呼び出す必要があります。あるいは、2つの呼び出しエンコーディングを区別するいくつかのフレーバーが必要です。 externがあなたのためにそれをしなかったら、分解を点検しなさい。 –

答えて

1

あなたはこれを変更する必要があります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ファイル:私はその後、ターボ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; 
} 

++ 1.01 TASM3.2):

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

そしてそれを実行してください:

c:\large.exe 
10