# برنامه نویسی سطح پایین > برنامه نویسی اسمبلی خانواده x86 > سوال: error 2000: Stack overflow

## امید خطیبی

سلام به تمام برنامه نویسان سایت.
من مشکلی در برنامه نویسی به زبان اسمبلی برام رخ داده که نمی دونم چگونه حل کنم آن را اگر کسی میدونه که چگونه باید حل کنم این مشکل را بگوید.
زمان اجرای برنامه به من این پیغام رو میده من باید چه کار کنم.
error 2000: Stack overflow
این پیغام هنگام اجرای برنامه اتفاق می افتد و برنامه های دیگر را هم امتحان کردم باز هم فایده ای نداشته.

----------


## saeed.afshari

کدی که نوشتی رو بزار تا بررسی کنم.

n software, a *stack overflow* occurs when too much memory is used on the call stack. The call stack contains a limited amount of memory, often determined at the start of the program. The size of the call stack depends on many factors, including the programming language, machine architecture, multi-threading, and amount of available memory. When too much memory is used on the call stack the stack is said to overflow, typically resulting in a program crash.

http://en.wikipedia.org/wiki/Stack_overflow

----------


## امید خطیبی

این کد این برنامه ای هست که من تو همین سایت برداشتم و هر بار که اون رو اجرا می کنم اون پیغام خطا رو میده که سرریز شده:
.MODEL SMALL

.STACK 64

.DATA

STR1 DB "ZOJ$"
STR2 DB "FARD$"

.CODE
MAIN PROC FAR

    MOV AX,@DATA
    MOV DS,AX
    ;-----
    MOV AX,4 ;ADADE MOREDE NAZAR / BL-> IF MOD IS 0 = EVEN

    MOV BL,2
    DIV BL
    CMP AH,0

    JNE LF

    MOV AH,09H
    LEA DX,STR1
    INT 21H
    JMP EXIT


    LF:
    MOV AH,09H
    LEA DX,STR2
    INT 21H


    EXIT:
    ;----
    MOV AH,00H
    INT 16H
    ;----
    MOV AX,4C00H
    INT 21H

MAIN ENDP
END MAINحالا این از کد و حالا شما به من بگویید باید برای رفع این مشکل باید چه کار بکنم.

----------


## pashaie

> حالا این از کد و حالا شما به من بگویید باید برای رفع این مشکل باید چه  کار بکنم.


آقا من این کد شما رو با emu8086 ران کردم ارور نداد، شما با چه برنامه ای کدت رو کامپایل می کنی؟

درضمن یه راه راحتر واسه تشخیص زوج یا فرد بود یه عدد اینه که بیت کم ارزششو چک کنی، اگه یک بود فرده و در غیر این صورت ذوج
واسه چک کردن هم می تونی از دستور شیفت به راست استفاده کنی
کد با استفاده از شیفت 

.MODEL SMALL

.STACK 64

.DATA

STR1 DB "ZOJ$"
STR2 DB "FARD$"

.CODE
MAIN PROC FAR

MOV AX,@DATA
MOV DS,AX
;-----
MOV AX, 4 ;ADADE MOREDE NAZAR / BL-> IF MOD IS 0 = EVEN
SHR AX, 1
JC  LF

MOV AH,09H
LEA DX,STR1
INT 21H
JMP EXIT


LF:
MOV AH,09H
LEA DX,STR2
INT 21H


EXIT:
;----
MOV AH,00H
INT 16H
;----
MOV AX,4C00H
INT 21H

MAIN ENDP
END MAIN

----------


## امید خطیبی

سلام من این برنامه را از اینترنت دانلود کردم و این کدی رو که داخل سایت گذاشته اید رو برداشتم اما از این خط زیر پیغام خطا می گیره و تازه من می خواهم این برنامه رو تغییر بدم به این شکل که من 6 عدد را وارد می کنم و برنامه باید به من بگوید که چه مقدار عدد زوج دارم و چه مقدار عدد فرد و کد داخل برنامه ای که Error می گیره این هست با همین برنامه ای که گفتید در سایت اجرا شده:
MOV AX,@DATA

----------


## pashaie

این کد رو امتحان کن ببین کار می کنه یا نه




data segment
    STR1 DB "ZOJ$"
    STR2 DB "FARD$"
    pkey db 13,10,"press any key...$"
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
; set segment registers:
    mov ax, data
    mov ds, ax
    mov es, ax


    MOV AX, 5 ;ADADE MOREDE NAZA
    SHR AX, 1
    JC  LF
    
    MOV AH,09H
    LEA DX,STR1
    INT 21H
    JMP EXIT
    
    
    LF:
    MOV AH,09H
    LEA DX,STR2
    INT 21H
    
    
    EXIT:


            
    lea dx, pkey
    mov ah, 9
    int 21h       
    
    ; wait for any key....    
    mov ah, 1
    int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h    
ends

end start ; set entry point and stop the assembler.

----------


## امید خطیبی

من دوباره با مشکل دیتا برخوردم و اون هم در این خط از کد شما هست.
 mov ax, data

----------


## امید خطیبی

و یک سوال دیگر ما زمانی که می خواهیم بین سه عدد بفهمیم کدوم ماکزیمم هست چگونه باید این کار رو بکنیم روش ساده این برنامه رو دارید یا نه.
من این برنامه رو نوشتم اما خیلی زیاد هست و نمی دونم باید چه کار کنم.

----------


## pashaie

> من دوباره با مشکل دیتا برخوردم و اون هم در این خط از کد شما هست.


جلب! 
البته من هنوز نمی دونم شما دارید با چی کد ها رو کامپایل می کنید. Masm? Tasm? Nasm? FASM?

امید وارم این یکی دیگه کارکنه - چون تو مد کام نوشتمش و دیگه ست کردن کد سگمنت و دیتا سگمنت نداره

name "mycode"

org  100h    
    MOV AX, 4 ;ADADE MOREDE NAZA
    SHR AX, 1
    JC  LF
    
    MOV AH,09H
    LEA DX,STR1
    INT 21H
    JMP EXIT
    
    LF:
    MOV AH,09H
    LEA DX,STR2
    INT 21H

    EXIT:        
    lea dx, pkey
    mov ah, 9
    int 21h       
    
    ; wait for any key....    
    mov ah, 1
    int 21h
    
    mov ax, 4c00h ; exit to operating system.
    int 21h 

ret  
    STR1 DB "ZOJ$"
    STR2 DB "FARD$"
    pkey db 13,10,"press any key...$"





> و یک سوال دیگر ما زمانی که می خواهیم بین سه عدد بفهمیم کدوم ماکزیمم هست  چگونه باید این کار رو بکنیم روش ساده این برنامه رو دارید یا نه.


این کار که خیلی سادست! احتمال کدی که پیدا کردی قاشوق رو دور سرش چرخونده!
شما یه اعدادتون رو اول می ریزید تو آرایه:
Array2 db -4,-7,5,7,6,-4,20,0,9,-15  

بعد مقدار اولین عنصور رو میریزید تو متغییر ماکزیمومتون

 lea bx, Array2    
    mov al, [bx]
    mov low, al


در آخر هم یه حلقه مینویسی که به تعداد یکی منهای تعداد کل اعداد داخل آرایه اجرا بشه و در هر مرحله عدد iام رو با مقدار متغییر ماکزیمم مقایسه می کنی اگه اعدد بزرگتر بود تو ماکزیمم جای کزین می کنی و در غیر این صورت حلقه رو ادامه می دی

اینم برنامه کامل واسه پیدا کردن *مینیمم *  :لبخند گشاده!: 

data segment     
    Array2 db -4,-7,5,7,6,-4,-20,0,9,-15  
    Low db ?
    pkey db 13,10,"press any key...$"
ends

stack segment
    dw   128  dup(0)
ends

code segment
start:
    mov ax, data
    mov ds, ax
    mov es, ax
    
    mov cx, 1
    lea bx, Array2    
    mov al, [bx]
    mov low, al
    inc bx
lblLoop:
    mov al, [bx]        
    cmp Low, al
    jl  lbl1
    mov Low, al
                          
lbl1:                  
    inc cx
    inc bx
    cmp cx, 9
    jb lblLoop
                   

    lea dx, pkey
    mov ah, 9
    int 21h
    
    mov ah, 1
    int 21h
    
    mov ax, 4c00h
    int 21h    
ends

end start

----------


## امید خطیبی

از شما ممنونم که به من کمک کردید و به سوالات من جواب دادید و شما یک سایتی رو می شناسید که کد های اسمبلی و کتابی جامع در مورد اسمبلی در ان باشد یا نه اگر دارید بگذارید تا همه از ان استفاده کنند.
باز هم ممنونم از این که به من کمک کردید.

----------


## امید خطیبی

راستی یک سوال دیگر هم برام پیش اومده که این هست اگر ما بخواهیم این اعداد رو از کاربر بگیریم و این کارها رو اعدادی که وارد شده است انجام دهیم چه باید بکنیم.

----------


## امید خطیبی

سوالی دیگر این که اگر بخواهیم این اعداد رو از کاربر بگیریم چی؟

----------


## امید خطیبی

باز هم سوالی دیگر:
اگر ما بخواهیم همانند برنامه های دیگر از کاربر درخواست تعدادی عدد بکنیم باید چه کار انجام دهیم.

----------


## pashaie

کتابی جامع در مورد اسمبلی
اگه زبانت خوبه پیش نهاد می کنم حتما و حتما کتاب Art of Assembly رو بخونی اینم لینک آنلاینش
http://www.arl.wustl.edu/~lockwood/c...ofasm/toc.html

سوالی دیگر این که اگر بخواهیم این اعداد رو از کاربر بگیریم چی؟ 		


> 


اون موقعس که پیرت در میاد! 
البته اگه بخوای اعداد تک رقمی رو فقط بخونی که کار خیلی سادست! یه کاراکتر از ورودی می خونی، اگه تو محدوده '0' تا '9' بود اونو منهای '0' میکنی تا به عدد تبدیل بشه و این عدد رو با عدد ماکزیممت مقایسه می کنی و ... (تو این روش دیگه نیازی به ذخیره اعداد تو آرایه نیست)

یه روش دیگه برای تبدیل کد اسکی یه عدد به مقدار اون عدد اینکه کد اسکی رو با 00Fh اند کنی چون کد اسکی اعداد در واقع از 30h تا 39h هست، این کار باعث می شه که اون 3 صفر بشه و فقط عدد باقی بمونه.

برای اعداد چند رقمی هم رسما باید ذجر بکشی .....
یا از کد زیر استفاده کنی



;*************************************************  ******************

; reads char from the keyboard into al
; (modifies ax!!!)
read_char       proc    near
        mov     ah, 01h
        int     21h
        ret
read_char       endp

;*************************************************  **************

; gets the multi-digit signed number from the keyboard,
; result is stored in cx. backspace is not supported, for backspace
; enabled input function see c:\emu8086\inc\emu8086.inc
scan_num        proc    near
        push    dx
        push    ax

        xor     cx, cx

        ; reset flag:
        mov     make_minus, 0

next_digit:

        call    read_char

        ; check for minus:
        cmp     al, '-'
        je      set_minus

        ; check for enter key:
        cmp     al, cr
        je      stop_input

        ; multiply cx by 10 (first time the result is zero)
        push    ax
        mov     ax, cx
        mul     ten                     ; dx:ax = ax*10
        mov     cx, ax
        pop     ax

        ; check if the number is too big
        ; (result should be 16 bits)
        cmp     dx, 0
        jne     out_of_range

        ; convert from ascii code:
        sub     al, 30h

        ; add al to cx:
        xor     ah, ah
        add     cx, ax
        jc      out_of_range    ; jump if the number is too big.

        jmp     next_digit

set_minus:
        mov     make_minus, 1
        jmp     next_digit

out_of_range:
        lea     dx, error
        call    puts

stop_input:
        ; check flag:
        cmp     make_minus, 0
        je      not_minus
        neg     cx
not_minus:

        pop     ax
        pop     dx
        ret
scan_num        endp


انارو هم تو دیتا سگمت بزار

make_minus      db      ?       ; used as a flag in procedures.
ten             dw      10      ; used as multiplier.

----------

