assembley compiler+ line and circle algorithem - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

assembley compiler+ line and circle algorithem


בלה

Recommended Posts

הי אני מחפש קומפיילר לאסמבלי, הורדתי כבר 2 ואחד הוא דמו שלא עושה build והשני סתם לא עובד.

אני כותב באסמבלי של 80286 (בעיקרון 8086 אבל כתוב בספר שלי שיש שימוש בכמה דברים מ- 286).

וגם אני מחפש אלגוריתם לציור מעגל, קוראים לו bresenham's circle algorithm.

אני יודע שאפשר לצייר מעגל עם sin ו- cos בדרך הרגילה אבל שמעתי שהאלגוריתם הזה הרבה יותר יעיל, ואלגוריתם לקו אני יודע רק בדרך y=mx+n.

למי שתוהה אני כותב ספריה גרפית ל- mode13h.

ואני מכיר את google... פשוט לא מצאתי שם.

תודה למי שיעזור.

עריכה: את האלגוריתם מצאתי http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/bresenham.html

אבל אני לא מבין אותו..

קישור לתוכן
שתף באתרים אחרים

האלגוריתם המקובל לציור קו ישר נקרא midpoint, ונראה די מכוער (כי מפרידים לשני מקרים אם m<1 או שלא).

הייתרון בו שהוא מאפשר חישוב במספרים שלמים, ומתבסס על זה שאתה צובר את השגיאה עד שהיא מגיעה לפיקסל שלם.

קישור לתוכן
שתף באתרים אחרים

תשובות לפי הסדר:

1) כדאי לדעת שמה ש"מקמפל" אסמבלי נקרא "אסמבלר". יש הבדל בין קומפיילר לאסמבלר.

אני מציע לך לחפש את watcom C אשר תומך ב-inline 386 assembler. זה יחסוך לך הרבה כאב ראש.

בכל מקרה הנה רשימה של אסמבלרים ל-X86:

http://www.thefreecountry.com/compilers/assemblers.shtml

2) הנה הסבר עלbresenham

http://en.wikipedia.org/wiki/Bresenham%27s_algorithm

(3

midpoint זה שם אחר לאלגוריתם של bresenham.

4) יש מליון לינקים בגוגל, אחד מהם בטח יעזור לך להבין את זה: http://www.gamedev.net/reference/articles/article767.asp

הלינק שהלכת עליו גרוע מאוד בהסברים. הדרך היחידה להבין מה הולך שם זה אם אתה כבר מכיר את הנושא לא רע ויש לך רקע מתמטי.

קישור לתוכן
שתף באתרים אחרים

אה ועוד דבר... הורדתי כמה קומפיילרים אבל כולם עושים לי errors מעצבנים כמו למשל שאני כותב P286N בהתחלה או שאני כותב DATASEG והסתכלתי על אחד בתוכניות לדוגמא ופשוט מציינים בו את האוגרים לשימוש הפרוצדורה.. אני רגיל לעשות push ax וכאלה לבד וגם בלי קשר אני לא רוצה לשנות את כל הסינטקס של הקוד אבל אני חייב?

קישור לתוכן
שתף באתרים אחרים

סבבה.. משום מה יש לי error מעצבן.. unmatched block nesting.

זה אומר לי על שורה בפרוצדורה savemode שמקבלת לתוך משתנה את מצב המסך הנוכחי. אני אדגיש את שורה מספר 50 שלפי הקומפיילר בה יש error.

אני משתמש ב- masm32 editor.

הנה חלקי הקוד הרלוונטיים לדעתי לארור אולי.. אבל אני לא רואה סיבה אליו.. אני אביא את שאר התוכנית אם צריך אבל לא נראה לי שהפונקציות draw_pixel ו- draw_line קשור כל כך לזה:)

; Michael's MODE 13h Function Library

.386

.model flat, stdcall

option casemap :none

.data

XONE DB 100 ; to store the x coordinate of initial point

YONE DB 80 ; to store the y coordinate of initial point

XTWO DB 75 ; to store the x coordinate of final point

YTWO DB 20 ; to store the y coordinate of final point

DELTAX DB ? ; to store the absolute value of x2-x1

DELTAY DB ? ; to store the absolute value of y2-y1

ERROR DB 0; if 2*error>deltax then y++ else y stay the same

STEEP DB ?; 0 if 0<m<1. or 1 if m>1

Y_STEP DB ?; if y0<y1 then y_step=0 else y_step=-1

COLOR DB 20;

XONE_BIGGER DB 0; 1 if x1>x2 else 0

YONE_BIGGER DB 0; 1 if y1>y2 else 0

VIDEOMODE DB ?; Store the current Video Mode

.code

start:

call SaveMode

call Set_13h_Mode

mov di, A000h ; adress for the screen buffer

mov es, di ; into es

call Draw_Line

call WaitForKeyPressed

call Set_Text_Mode

exit:

mov ah, 04CH

mov al, 0

int 21H

SaveMODE PROC

push ax

mov ah,0FH ; function 0fh - get current mode

int 10h ; video service call

mov VIDEOMODE,al ; save current mode

pop ax

ret

SAVEMODE endp

Set_13h_Mode PROC

push ax

mov ax, 0013h

int 10h

pop ax

ret

Set_13h_Mode endp

Set_Text_Mode PROC

push ax

mov ax, VIDEOMODE

int 10h

pop ax

ret

Set_Text_Mode endp

קישור לתוכן
שתף באתרים אחרים

זה ניחוש אבל אולי מדובר ב-Case Sensitivity? שים לב שהשורה המודגשת כולה ב-caps בניגוד לשורה הפותחת את הבלוק.

חוץ מזה, כדאי לך להשתמש ב-code tag של הפורום. תסמן קטע קוד ואז תלחץ על הכפתור שנראה כמו #.

אה, ויש לך באג: mov ax,VIDEOMODE אבל VIDEOMODE מוגדר כ-byte. סתם במקרה ראיתי.

קישור לתוכן
שתף באתרים אחרים

זה ניחוש אבל אולי מדובר ב-Case Sensitivity? שים לב שהשורה המודגשת כולה ב-caps בניגוד לשורה הפותחת את הבלוק.

חוץ מזה, כדאי לך להשתמש ב-code tag של הפורום. תסמן קטע קוד ואז תלחץ על הכפתור שנראה כמו #.

אה, ויש לך באג: mov ax,VIDEOMODE אבל VIDEOMODE מוגדר כ-byte. סתם במקרה ראיתי.

תודה על הבאג.. תיקנתי.

גם שיניתי את שם הפונקציה אז זה לא case sensitive.

לפני שהיה לי את הפונקציה savemode הייתי משתמש בפונקציה של טקסט מוד עם mode 3 אבל אז זה שם לי את ה- error שם.

אתה יכול להסביר על code tag? לא כל כך הבנתי.

עריכה: יש לי עדיין את אותו error כמו שאמרתי שאני עושה build, אבל ניסיתי לעשות compile (בילד זה הכל נכון?) וזה כתב לי שם

"cannot open rsrc.res for reading ".

קישור לתוכן
שתף באתרים אחרים

לא השתמשתי ב-MASM מעולם אז אין לי מושג מה הוא אומר לך. כבר שנים שלא כתבתי assembly רציני, אז אני כבר לא זוכר אפילו את TASM שהשתמשתי בו בעבר.

אם אני מנחש את MASM נכון, אז .code אומר לקומפיילר וללינקר להכניס את הסמלים שאתה יוצר ל-text section בקובץ המקומפל.

.data יכנס ל-data section.

מקובל להושיב קוד ונתונים באזורים שונים בזכרון. זה מאוד תלוי בארכיטקטורה מה ומי בדיוק, אבל לפי מיטב זכרוני בדוס הקוד יושב ב-code section והנתונים ב-data section.

אם היית עובד במודל זכרון segmented אז CS היה מצביע על ה-code section ו-DS היה מצביע על data section (למרות שה-S הכוונה ל-segment). אתה לא עובד במוד הזה (למזלך!) אז זה קצת אחרת.

כמו שאמרתי, אני כבר שנים לא נגעתי ב- assembly, אולי מישהו שזוכר יותר טוב יעזור?

קישור לתוכן
שתף באתרים אחרים

אני מתכוון שב-protected mode הזכרון לא מחולק לסגמנטים.

אם אתה כותב מודול (.obj) אשר מיועד להתלנקג' עם C (לדוגמא) אז אתה לא אמור לשחק עם הסגמנטים.

אם אתה כותב קובץ להרצה (exe) אז אתה כן אמור לטפל בזה, וכן לדאוג ל-entry point.

אם אתה כותב קובץ .COM אז אתה גם צריך לדאוג ל-100h בתים בתחילת הקובץ, וה-entry point ימצא אחריהם.

אני ממש ממש לא זוכר הרבה. תמצא ספר על תכנות אסמבלי של . בעבר היו כמה טובים מאוד.

קישור לתוכן
שתף באתרים אחרים

  • 2 שבועות מאוחר יותר...

טוב נכנעתי והחלטתי לעזוב את masm שעושה לי בעיות בקומפייל ולכתוב ב- c עם inline assembly.

עכשיו אני משתמש ב- tc 2.01 בשביל לקמפל ונוצר לי error: in-line assembly not allowed in function (func name here.

למשל בקוד הזה... מה לא בסדר פה? למה יש לי errors מכל פקודות האסמבלי האלו?:

void Put_Pixel (byte XONE1, byte YONE1, byte COLOR1)

{

asm push ax

asm push dx

asm push bx

asm mov al, YONE1

asm mov dx,ax

asm shl dx, 8

asm shl ax, 6

asm add ax, dx

asm mov bl , XONE1 // bx gets x

asm add bx, ax // bx now get the whole offset

asm mov di, bx

asm mov dl, COLOR1 // dl get the color

asm mov es:[di], dl

asm pop bx

asm pop dx

asm pop ax

}

קישור לתוכן
שתף באתרים אחרים

אני מצטער, עבר יותר מדי זמן. אבל הנה כמה הצעות:

במקום לרשום asm בכל שורה, תנסה לרשום asm { bla bla bla } כלומר להקיף את כל קטע האסמבלי ב-asm { }. אני זוכר שיש איזשהו קומפילר של בורלנד שזה עובד בו. יתכן שצריך borlandC 3.1 בשביל זה.

חוץ מזה יש לך כמה באגים:

1) שכחת mov ax,0a000h ואז mov es,ax. (יש עוד שיטות לעשות את זה כמובן).

2) שכחת לאפס את AH בזמן שהעברת ל-AL את YONE1. לדוגמא: xor ax,ax ואז mov al,YONE1

3) יכול להיות ש-X יהיה גדול מ-255 (לדוגמא 319) ואז BYTE לא מספיק. תגדיר אותו בגודל של 16 ביטים ותעשה MOV BX,X. אם תעשה משהו דומה עם Y זה יפתור לך את הבעיה שב-(2).

4) אין צורך לעשות MOV DI,BX כיוון שאפשר להשתמש ב-BX כפוינטר ישירות: MOV es:[bX],DL.

קישור לתוכן
שתף באתרים אחרים

אני מצטער, עבר יותר מדי זמן. אבל הנה כמה הצעות:

במקום לרשום asm בכל שורה, תנסה לרשום asm { bla bla bla } כלומר להקיף את כל קטע האסמבלי ב-asm { }. אני זוכר שיש איזשהו קומפילר של בורלנד שזה עובד בו. יתכן שצריך borlandC 3.1 בשביל זה.

חוץ מזה יש לך כמה באגים:

1) שכחת mov ax,0a000h ואז mov es,ax. (יש עוד שיטות לעשות את זה כמובן).

2) שכחת לאפס את AH בזמן שהעברת ל-AL את YONE1. לדוגמא: xor ax,ax ואז mov al,YONE1

3) יכול להיות ש-X יהיה גדול מ-255 (לדוגמא 319) ואז BYTE לא מספיק. תגדיר אותו בגודל של 16 ביטים ותעשה MOV BX,X. אם תעשה משהו דומה עם Y זה יפתור לך את הבעיה שב-(2).

4) אין צורך לעשות MOV DI,BX כיוון שאפשר להשתמש ב-BX כפוינטר ישירות: MOV es:[bX],DL.

בהתחלה הפונקציה הזאת הייתה עם בלוק וזה גם לא עבד.. אבל אפשר גם ככה ושיניתי את זה כדי לבדוק אם זה יעבוד בצורה הזאת.. כמו כן בפונקציות יותר ארוכות שמשתמשות ב- jump השתמשתי בשיטה הזאת כי את התוויות כותבים בשפת c ולא כפקודת אסמבלי (ככה קראתי לפחות) ובמקום לסגור את הבלוק ולפתוח מחדש כל פעם לפני ואחרי תווית פשוט כתבתי לכל פקודה אחרת את ה- asm לפני בלי להסתבך.

בקשר להעברת המקטע ל- es, כתבתי את הפקודות האלה בפונקציה main אבל אני מניח שעדיף לשים את זה באמת בפונקציה הזאת... לא שזה גרם באג אבל זה יותר נכון בדרך שאתה אמרת.

תודה על ההצעות על הקטע שביט לא מספיק אני יודע שמתי לב בדיוק שניה לפני שבדקתי את התשובה שלך אבל תודה:)

ותודה בקשר להערה 4.

אני משתמש ב- tc2.01 אבל לפי מה שאני יודע הוא תומך באסמבלי וזה לא שהסינטקס שלי לא נכון.. אני כמעט בטוח שהוא נכון.

הקומפיילר מבין שזה in-line assembly כי זה כותב לי "cannot use in-line assembly in function put_pixel ".

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...