PDA

View Full Version : سوال: error 2000: Stack overflow



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

saeed.afshari
یک شنبه 16 خرداد 1389, 09:28 صبح
کدی که نوشتی رو بزار تا بررسی کنم.

n software, a stack overflow occurs when too much memory (http://en.wikipedia.org/wiki/Computer_memory) is used on the call stack (http://en.wikipedia.org/wiki/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.[/URL]

[url]http://en.wikipedia.org/wiki/Stack_overflow (http://en.wikipedia.org/wiki/Stack_overflow#cite_note-fortran1-0)

امید خطیبی
یک شنبه 16 خرداد 1389, 13:19 عصر
این کد این برنامه ای هست که من تو همین سایت برداشتم و هر بار که اون رو اجرا می کنم اون پیغام خطا رو میده که سرریز شده:

.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
یک شنبه 16 خرداد 1389, 18:00 عصر
حالا این از کد و حالا شما به من بگویید باید برای رفع این مشکل باید چه کار بکنم.
آقا من این کد شما رو با 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

امید خطیبی
یک شنبه 16 خرداد 1389, 19:26 عصر
سلام من این برنامه را از اینترنت دانلود کردم و این کدی رو که داخل سایت گذاشته اید رو برداشتم اما از این خط زیر پیغام خطا می گیره و تازه من می خواهم این برنامه رو تغییر بدم به این شکل که من 6 عدد را وارد می کنم و برنامه باید به من بگوید که چه مقدار عدد زوج دارم و چه مقدار عدد فرد و کد داخل برنامه ای که Error می گیره این هست با همین برنامه ای که گفتید در سایت اجرا شده:


MOV AX,@DATA

pashaie
یک شنبه 16 خرداد 1389, 19:50 عصر
این کد رو امتحان کن ببین کار می کنه یا نه





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.

امید خطیبی
دوشنبه 17 خرداد 1389, 08:51 صبح
من دوباره با مشکل دیتا برخوردم و اون هم در این خط از کد شما هست.


mov ax, data

امید خطیبی
دوشنبه 17 خرداد 1389, 08:58 صبح
و یک سوال دیگر ما زمانی که می خواهیم بین سه عدد بفهمیم کدوم ماکزیمم هست چگونه باید این کار رو بکنیم روش ساده این برنامه رو دارید یا نه.
من این برنامه رو نوشتم اما خیلی زیاد هست و نمی دونم باید چه کار کنم.

pashaie
دوشنبه 17 خرداد 1389, 16:04 عصر
من دوباره با مشکل دیتا برخوردم و اون هم در این خط از کد شما هست.
جلب!
البته من هنوز نمی دونم شما دارید با چی کد ها رو کامپایل می کنید. 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

امید خطیبی
دوشنبه 17 خرداد 1389, 17:10 عصر
از شما ممنونم که به من کمک کردید و به سوالات من جواب دادید و شما یک سایتی رو می شناسید که کد های اسمبلی و کتابی جامع در مورد اسمبلی در ان باشد یا نه اگر دارید بگذارید تا همه از ان استفاده کنند.
باز هم ممنونم از این که به من کمک کردید.

امید خطیبی
دوشنبه 17 خرداد 1389, 17:12 عصر
راستی یک سوال دیگر هم برام پیش اومده که این هست اگر ما بخواهیم این اعداد رو از کاربر بگیریم و این کارها رو اعدادی که وارد شده است انجام دهیم چه باید بکنیم.

امید خطیبی
دوشنبه 17 خرداد 1389, 17:15 عصر
سوالی دیگر این که اگر بخواهیم این اعداد رو از کاربر بگیریم چی؟

امید خطیبی
دوشنبه 17 خرداد 1389, 18:56 عصر
باز هم سوالی دیگر:
اگر ما بخواهیم همانند برنامه های دیگر از کاربر درخواست تعدادی عدد بکنیم باید چه کار انجام دهیم.

pashaie
دوشنبه 17 خرداد 1389, 19:00 عصر
کتابی جامع در مورد اسمبلی
اگه زبانت خوبه پیش نهاد می کنم حتما و حتما کتاب Art of Assembly رو بخونی اینم لینک آنلاینش
http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/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.