يه سوال درباره‌ي c++ 5.02

در اين بخش مي‌توانيد در مباحث مربوط به زبانهاي بر پايه C به بحث بپردازيد

مدیران انجمن: athlon64x2, abbas.m.k, شوراي نظارت

ارسال پست
New Member
پست: 1
تاریخ عضویت: جمعه 21 مهر 1385, 2:43 am

يه سوال درباره‌ي c++ 5.02

پست توسط arman.m » چهار شنبه 27 دی 1385, 12:54 am

سلام
شنيدم که بورلند c++ داره ويژگی تبديل c++ به اسّمبلی هست يعنی ميتونه يه برنامه به زبان c ++ رو به زبانه اسّمبلی تبديل کنه

لطف کنيد من و با اين تکنيک آشنا کنيد

متشکّرم

Colonel II
Colonel II
پست: 90
تاریخ عضویت: پنج شنبه 9 شهریور 1385, 9:15 pm
سپاس‌های دریافتی: 9 بار

Re: يه سوال درباره‌ي c++ 5.02

پست توسط athlon64x2 » چهار شنبه 27 دی 1385, 2:50 am

arman.m نوشته شده:سلام
شنيدم که بورلند c++ داره ويژگی تبديل c++ به اسّمبلی هست يعنی ميتونه يه برنامه به زبان c ++ رو به زبانه اسّمبلی تبديل کنه

لطف کنيد من و با اين تکنيک آشنا کنيد

متشکّرم


سلام دوست عزيز و گرامي

بله همينطوره . تمام نسخ بورلند سي امکان ارائه خروجي بصورت ليست assembly opcode رو دارند.
راستش من تاپيک شما رو قبلا ديدم و به نظرم رسيد قصد داريد برنامه اي به زبان سي++ بنويسيد و سپس از سورس اسمبلي بجاي يک برنامه اسمبلي که هيچ جاي پايي از برنامه سي اوليه در اون نباشه استفاده کنيد متاسفانه من با چنين قابليتي برخورد نکرده ام و آنچه ديده ام و اتفاقا زياد استفاده کرده ام خروجي سورس اسمبلي از کمپايلر بوده که فقط مناسب ويرايش و بهينه سازي و کمپايل مجدد است.

اگر برنامه شما سورس c++ باشد که سورس اسمبلي ايجاد شده بخاطر اشاراتي که به this در هر تابع رد ميکنه و crt پيچيده تر فوق العاده نامفهومه. وانگهي c++ زباني شيي گرا و اسمبلي (آنهم ماکرو يا توربو اسمبلي) زباني procedural است که اساسا طراحي متفاوتي رو ميطلبند. پس توصيه اول C++ رو فراموش کنيد C مناسبتر است.

حال در C اگر برنامه رو در مود حافظه اي غير از compact کمپايل کنيد عملا بي فايده است چرا که کد اسمبلي که دريافت کنيد نيز براي لينک موفق نيازمند c0.lib خواهد بود که البته سورس اسمبلي آن نيز تا جاييکه در خاطرم هست روي هارد نصب ميشد اما هر کس با اولين نظر آماده سازي stack برنامه و stack ويژه crt رو ميبينه و مشخصه که سورس سي++ بوده پس عملا قيد exe رو بزنيد و به سراغ com بريد. حالا کار کمي آسانتر است. براي com در مود compact سورس اسمبلي که به شما ميده ميتونه با تغييراتي کمپايل و بدون نياز به c0.lib لينک بشه که هدف ماست . البته مشکل اينه که در تمام موارد صدا زدن توابع استاندارد و حتي بعضي توابع داخلي به crt اشاره ميکنه و بطور مشخص ميتونيد در سورس اسمبلي دستوارتي که آدرس تابع رو در رجيسترها لود ميکنند ببينيد که اين معضله چون نميخوايد معلوم شه سي بوده. 2 راه هست . يا اينکه کلا تا جاييکه ميتونيد از وقفه ها (داس و بيوس) براي کار با کيبورد خروجي و فايلها استفاده کنيد يا از توابع inline استفاده کنيد که خوشبختانه خوبي توربو سي اينه که براي خيلي از اين توابع متناظر هاي داخلي هم داره که بجاي صدا زدن تابع کل سورس تابع رو بصورت اسمبلي جايگزين ميکنه (بيشتر مواقع نام تابع ها يکيه و فقط کافيه يه _ قبلش اضافه کنيد) ولي بازهم بطور کل بي نياز از ويرايش نخواهيد بود بخصوص که سر و شکل يک برنامه مناسب و خوب اسمبلي رو هم نهايتا نخواهد داشت .

راستش سالهاي دور دوستي داشتم که به اين واحد در دروس دانشکده علاقه نداشت و تصميم داشت يک برنامه سي رو دسورس کنه. مطالب بالا از اين تجربه حاصل شد و سرانجام بهتر ديدم که يک برنامه اسمبلي براش بنويسم و کل مطلب رو درز بگيرم چون اين ويرايش و پيرايش خيلي وقت گير بود. اما اگر قصدتان بهينه سازي بخشهاي حياتي برنامه تان باشد اتفاقا اين کار رو زياد انجام دادم گو اينکه به تجربه ميتونم بگم نوشتن فانکشن لازم به زبان اسمبلي کمپايل کردن اون بصورت lib يا obj و لينک کردن اون با بقيه برنامه به زبان سي خيلي سريعتره و بخصوص ديباگ بعديش راحت تر. اگر هم صرفا ميخواهيد داخل يک لوپ رو بهينه سازي کنيد بازهم دستور asm درون سورس کد c++ خيلي راحت تره و bc خيلي راحت سورس شما رو کمپايل ميکنه . در واقع گرفتن سورس اسمبلي از يک برنامه سي به نظر من بدترين روش براي بهينه سازي است چرا که کافيه يک خط به برنامه سي خودتون اضافه و کم کنيد يا تغيير بدين که مجبور شين از اول تمام تغييرات در سورس اسمبلي رو تکرار کنيد.

اگر هنوز تمايل داريد بفرماييد تا option هاي کمپايلر رو خدمتتون معرفي کنم و در حد اطلاعاتم در خدمتتون باشم. به هر حال براي کمک بيشتر نياز مند اطلاعات بيشتر از سوي شما هستم.

ارادتمند شما
نعيمي

Major
Major
نمایه کاربر
پست: 236
تاریخ عضویت: جمعه 14 مهر 1385, 4:48 pm
محل اقامت: تهران-اهواز
سپاس‌های دریافتی: 3 بار
تماس:

پست توسط shahram_sampad » چهار شنبه 27 دی 1385, 3:03 am

تو منو هاش بگرد البته من تو اين ورژن خودم پيدا نكردم اما تو ورژن هاي تخت داس معمولا راحت پيداش ميكني اين گزينه رو
عمریست که از حضور او جا ماندیم/ در غربت سرد خویش تنها ماندیم/ او منتظر ماست که ما برگردیم/ ماییم که در غیبت کبرا ماندیم

Colonel II
Colonel II
پست: 90
تاریخ عضویت: پنج شنبه 9 شهریور 1385, 9:15 pm
سپاس‌های دریافتی: 9 بار

پست توسط athlon64x2 » پنج شنبه 28 دی 1385, 3:26 am

سلام دوست عزيز و گرامي

بورلند سي++ نسخه تحت ويندوز چيزي نيست جز يک اديتور و IDE که امکان ديباگ شامل break point و trace و .. رو فراهم ميکنه . کليه عمليات کمپايل لينک و make خيلي ساده به کنسول ارسال ميشن به همين دليل معمولا سويچ هاي پيشرفته در منوها در دسترس نيست . در IDE هاي داس توربو سي و بورلند سي هم وضع به همين منواله . براي دستيابي به سورس اسمبلي فقط نياز به کمپايل سورس سي هست بدون الزام به که حتي اگر سورس شما مجموعه اي از فانکشنها بوده و اجرايي هم نباشه هم مشکلي وجود نداره و الزامي نيست برنامه شما حتما اجرايي باشه.

اما بطور خلاصه شما بايد

سورس رو صرفا کمپايل کنيد
کمپايل با ايجاد سورس اسمبلي باشه يا فقط سورس سي رو به اسمبلي تبديل کنه
مدل حافظه رو tiny انتخاب کنيد تا برنامه شما فقط از يک سگمنت براي کد + ديتا + stack استفاده کنه وگرنه کار کمي سخت ميشه . همونطوري که در پست اولم نوشتم سورس اين مدل حافظه خيلي راحت تر ويرايش ميشه و دليلش رو هم بيان کردم (مدل حافظه tiny است متاسفانه از دستم در رفته و compact نوشتم در پست اول که عذر ميخوام)

BCC -c -S -Ipath -od -pr -mt file.c

دقت کنيد که آپشنها و سويچها case sensitive هستن و حتما به upper , lower case بودن کاراکترها به همين ترتيب فوق توجه کافي مبذول داريد

سويچ -od باعث ميشه که هيچ optimization انجام نشه که دو اثر داره. اولا کد اسمبلي شما ارتباط يک به يک و پيوسته با سورس سي داره و دوما از تغيير جنس متغير يا تبديل خودبخود اون از لوکال به رجيستر جلوگيري ميشه و به اين شکل راحت تر ميتونيد مسير برنامه رو پيگيري کنيد

سويچ -pr باعث ميشه که از روش fast calling يعني ارسال پارامترهاي فانکش در رجيستر استفاده بشه که روش مرسوم در اسمبلي است و اگر ميخواهيد سر و شکل برنامه شما به يک برنامه ارژينال اسمبلي شبيه باشه کمي کمک ميکنه. البته اين وقتي است که توابع شما تعداد معدود پارامتر دريافت ميکنند يعني توابعي بودند که فرضا اگر قرار بود اونها رو به اسمبلي بنويسيد از روش معرفي پارامتر در تعريف پروسه در همون خط DEF PROC استفاده ميکرديد و نام متغير و رجيستر متناظر رو معرفي ميکرديد ولي اگر تابع شما تعداد زيادي پارامتر دريافت ميکنه قاعدتا بايد از پشته استفاده کنيد. بسته به تجربه خودتون يکي رو انتخاب کنيد . البته در اين زمينه توافق صد در صد نيست و بعضي ها روش پاسکال رو ميپسندند که پشته رو در تابع صدا زننده rewind ميکنه و ويراشش آسونتره بعدا و بعضي هم روش C رو که کثيف! اما سريع و راحته منظور همون ret n آخر پروسه هست که پشته رو rewind ميکنه . البته يادتون باشه ترتيب ارسال پارامترها در C و Pascal برعکس همه که اگر بخواهيد با روش sp+n کار کنيد حتما به اين قضيه دقت کنيد.

سويچ -c هم سبب ميشه که سورس شما فقط کمپايل بشه و به لينکر ارسال نشه چون نيازي بهش نداريد قراره برنامه شما از اسمبلي سورس کمپايل مجدد و لينک بشه

سويچ -mt که هم براي کمپايل در مود tiny memory هست

سويچ I هم ادرس فولدر INCLUDE هست براي هدرها و در ضمن حتما مسير رو به I بچسبونيد و فاصله نگذاريد مثلا BCC -IC:\BCC\BCC5\INCLUDE درسته.

همچنان منتظر پاسخ شما هستم و در حد توانم با خوشحالي در خدمتتون خواهم بود.

ارادتمند
نعيمي

Major
Major
نمایه کاربر
پست: 236
تاریخ عضویت: جمعه 14 مهر 1385, 4:48 pm
محل اقامت: تهران-اهواز
سپاس‌های دریافتی: 3 بار
تماس:

پست توسط shahram_sampad » شنبه 11 فروردین 1386, 12:57 am

سلام دوستان آقا من قبلا با string درC++ کار ميکردمvisual studio و يادمه مشکلي نداشت اما الان براي پروژه يکي از درس ها گفتن فقط با برلند بايد باشه (من از 5.02 استفاده ميکنم و همچنين اون ورژن برلند تحت داس )اما تو برلند string اذيت ميکنه و مثلا اصلا getline() رو نميشنا سه... لطفا کمک کنيد چي کار کنم؟

يه سوال ديگه هم اينکه با چه دستوري از string ميشه از يه فايل text به مقدارهاي خاص خواند؟مثلا يه بايت يه بايت و 10 کيلو بايت 10 کيلو بايت و ...


پيشاپيش از کمکتون ممنونم...فقط خواهش ميکنم اگه ميتونيد سريع کمک کنيد...

راستي يه چيز هم بگم که براي سوال اولم خودم تنها راهي که پيدا کردم اين بود که از يه کلاس open source به نام pstring استفاده کنم... اما ميترسم تو بقيه پروژه به مشکل بر بخورم... چون با اين کلاس جديد آشنايي ندارم...مثلا همون طور که گفتم نميدونم چه طور با مقدار هاي مختلف بافر بخونم؟؟؟؟؟
عمریست که از حضور او جا ماندیم/ در غربت سرد خویش تنها ماندیم/ او منتظر ماست که ما برگردیم/ ماییم که در غیبت کبرا ماندیم

Colonel II
Colonel II
پست: 90
تاریخ عضویت: پنج شنبه 9 شهریور 1385, 9:15 pm
سپاس‌های دریافتی: 9 بار

پست توسط athlon64x2 » شنبه 11 فروردین 1386, 6:59 pm

shahram_sampad نوشته شده:سلام دوستان آقا من قبلا با string درC++ کار ميکردمvisual studio و يادمه مشکلي نداشت اما الان براي پروژه يکي از درس ها گفتن فقط با برلند بايد باشه (من از 5.02 استفاده ميکنم و همچنين اون ورژن برلند تحت داس )اما تو برلند string اذيت ميکنه و مثلا اصلا getline() رو نميشنا سه... لطفا کمک کنيد چي کار کنم؟


سلام دوست بسيار عزيز
ببخشيد پاسخ شما دير شد البته بهتر بود سوال رو در انجمن برنامه نويسي مطرح کنيد و مسلما سريعتر به جواب ميرسيديد. کلاس string در borland c++ واقع در cstring.h يک پياده سازي اختصاصي است که اساسا با پياده سازي string در ويژوال سي فرق داره. بورلند از اين کلاس بطور گسترده در ساير کلاسهاي خودش نيز استفاده کرده و عملا پياده سازي اصلي string در بورلند سي هست . البته بورلند کلاس مورد استقاده در ويژوال سي يعني std::string رو هم داره که در هدر فايل string.h قرار داده که البته ورژن آن قديمي است و ويرايش نيز شده است. بر خلاف آن ويژوال سي پياده سازي string رو بطور کامل از طريق stl انجام ميده که فوق العاده بهتر و کاملتر هست البته در MFC و ATL پياده سازي هاي اختصاصي هم داره اما کلاس اصلي همين std::string هست که انتخاب بسيار بهتري هم هست . البته stl متعلق به ميکروسافت نيست بلکه توسط AT&T و بعده ها HP طراحي و منتشر شده و بعدها به ANSI C++ اضافه شد . شما ميتونيد به راحتي آخرين ورژن اين پکيج رو داونلود کنيد و در بورلند سي مورد استفاده قرار بديد . آخرين نسخه يعني 3.3 که البته قديمي است رو ميتونيد از لينک زير بگيريد . بورلند سي بدون دستکاري اين هدر ها رو کمپايل ميکنه اما در عمل مشکلات بسيار زيادي با template ها و کتابخانه هاي ساخته شده بر اساس اونها داره . اساسا اغلب کمپايلر ها با template library ها مشکل داشتند و دارند و جالبه بدونين هنوز gc++ با همين stl ده سال قديمي مشکلاتي داره و پچ براي حل اين مشکلات منتشر ميشه يا ورژن هاي دستکاري شده از stl رو مورد استفاده قرار ميدن (کاري که ميکروسافت در تمام نسخ vc از 5 به بعد انجام داد و همچنان نسخه همراه vc8 دستکاري شده است! که البته تغيير کد نيست و صرفا غير فعال سازي يکسري warning ها و چند مورد اختلاف syntax هست).
[لینک خارجی برای کاربران مهمان مخفی است، لطفا برای مشاهده لینک ثبت نام نموده و یا وارد سایت شوید]


يه سوال ديگه هم اينکه با چه دستوري از string ميشه از يه فايل text به مقدارهاي خاص خواند؟مثلا يه بايت يه بايت و 10 کيلو بايت 10 کيلو بايت و ...


استفاده از stringبراي اينکار امکانپذير اما bad programming است. به اين منظور بطور خلاصه با fopen يک FILE بدست مياريد سپس سايز string رو با اندازه مناسب prealloc کرده و با fread ميخونيد که البته راه غلطي نيست اما linear است مگر اينکه کلاسهاي اختصاصي براي مديريت ايجاد و آزادسازي حافظه بنويسيد . روش درست اين کار در stl استفاده از iostream هست که براي مقاصد متفاوت input/output و حافظه/ديسک اختصاصي شده اند . متاسفانه به هيچ کمپايلري اينجا دسترسي ندارم تا نمونه قابل اجرا ارسال کنم و اجبارا سودو کد مينويسم که اميدوارم بر اساس اون به راحتي کد نهايي رو بنويسيد.

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

کد: انتخاب همه


ifstream ifs;
ifs.open(filename)


خواندن يک کاراکتر

کد: انتخاب همه

char c;

ifs.read (&c , 1 );


خواندن يک خط از فايل تکست

کد: انتخاب همه

string s;

string::getline(ifs, s);


خواندن يک کيلوبايت در يک string

کد: انتخاب همه

char *c = new char[1<<10];
string s;

ifs.read(&c, 1<<10);
s.Assign(c);
...
...
...
delete c;



البته راه بهتر استفاده از بافر/استريم درون حافظه اي يعني strstram هست که البته ميتوانيد از آن string بخوانيد و پروسس کنيد با getline يا ساير توابع. توجه کنيد که بيشتر توابع خواندن istream با رسيدن به newline برميگردن که با هدف شما که خواندن تعداد بايت مشخص از استريم هست (عملا شما بايت استريم لازم داريد) منافات دارد . translation + formatting + هندلينگ کاراکترهاي خاص تفاوت byte stream و string هست.

راستي يه چيز هم بگم که براي سوال اولم خودم تنها راهي که پيدا کردم اين بود که از يه کلاس open source به نام pstring استفاده کنم... اما ميترسم تو بقيه پروژه به مشکل بر بخورم... چون با اين کلاس جديد آشنايي ندارم...مثلا همون طور که گفتم نميدونم چه طور با مقدار هاي مختلف بافر بخونم؟؟؟؟؟


دوست خوبم همونطور که اشاره کردم استفاده از کلاس string و مديريت فايلهاي borlandC++ رو اصلا پيشنهاد نميکنم و استفاده از stl رو به دلايل متعدد توصيه ميکنم البته ميتوانيد از کلاسهاي اوپن سورس ديگه هم استفاده کنيد اما هيچکدام به اندازه std::string مورد استفاده قرارنگرفته و تست نشده اند.
در اولين فرصت که به يک پي سي داراي کمپايلر سي دسترسي پيدا کردم نمونه برنامه رو نوشته و براتون ارسال خواهم کرد همچنين اگر کمي با جزئيات بيشتر توضيح بديد ميتونم بيشتر کمک کنم و کلاسهاي مرتبط تر رو معرفي کنم . در صورت تمايل به ادامه لطفا در انجمن برنامه نويسي مطرح بشه تا نظم سايت هم حفظ گردد.

ارادتمند
نعيمي
آخرین ويرايش توسط 2 on athlon64x2, ويرايش شده در 0.

Major
Major
نمایه کاربر
پست: 236
تاریخ عضویت: جمعه 14 مهر 1385, 4:48 pm
محل اقامت: تهران-اهواز
سپاس‌های دریافتی: 3 بار
تماس:

پست توسط shahram_sampad » شنبه 11 فروردین 1386, 8:50 pm

آقا قربانت خيلي ممنون...ميرم امتحان ميکنم... ان شا الله که راه بيفته کارم...

ان شا الله دوباره مزاحم ميشم... :)
عمریست که از حضور او جا ماندیم/ در غربت سرد خویش تنها ماندیم/ او منتظر ماست که ما برگردیم/ ماییم که در غیبت کبرا ماندیم

Major
Major
نمایه کاربر
پست: 236
تاریخ عضویت: جمعه 14 مهر 1385, 4:48 pm
محل اقامت: تهران-اهواز
سپاس‌های دریافتی: 3 بار
تماس:

پست توسط shahram_sampad » یک شنبه 12 فروردین 1386, 1:47 am

با اين کدها نشد
عمریست که از حضور او جا ماندیم/ در غربت سرد خویش تنها ماندیم/ او منتظر ماست که ما برگردیم/ ماییم که در غیبت کبرا ماندیم

Colonel II
Colonel II
پست: 90
تاریخ عضویت: پنج شنبه 9 شهریور 1385, 9:15 pm
سپاس‌های دریافتی: 9 بار

پست توسط athlon64x2 » یک شنبه 12 فروردین 1386, 5:08 am

shahram_sampad نوشته شده:با اين کدها نشد


سلام دوست خوبم
شرمنده که به زحمت افتاديد اما همونطور که در پست قبلي هم ذکر کرده بودم اونها Pseudo code هستند نه code. در واقع فقط يک guideline هستند که شما بر اساس اون بايد کد رو مينوشتيد و قطعا به همون شکل قابل اجرا نبودند. متاسفانه روي اين پي سي هيچ کمپايلري نبود تا سورس تست شده ارسال کنم. داونلود بورلند سي++ 5.02 و stl 3.3 به پايان رسيد و اميدوارم اين نمونه کد کامل مشکل شما رو حل کنه که البته تست شده هست.

دقت کنيد که نسخه stl همراه بورلند (در اونجا به نام borland c++ standard library 7 خونده شده ) در واقع نسخه دستکاري شده و همراه اضافات 2.7 stl هست حتما از نسخه جديدي که آدرسش رو دادم به همراه آخرين پچ هاي بورلند براي 5.02 استفاده کنيد . چه بهتر که از بورلند سي++ 5.5 استفاده نماييد چون نسخه قديمي در تمپليت ها باگ داره و اگر کد زير رو بدون نصب فايلهاي نسخه جديد در بورلند 5.02 کمپايل کنيد نميتونه وراثت template ها رو به درستي resolve کنه و روي getline پيغام خطا ميگيريد که با استفاده از نسخه جديد stl و اخرين پچهاي بورلند حل ميشه . البته نسخه 5.5 بورلند سي بدون مشکل سورس رو کمپايل ميکنه.

اين نمونه کد هر 3 کاري که فرموديد (خوندن بايت به بايت-کيلوبايت به کيلوبايت و خط به خط در string ) رو نشون ميده. فايل films.txt يک فايل تکست هست که بهتره چند کيلوبايت باشه تا راحت تر تست کنيد. فايل نمونه در اين تست 270 کيلوبايت بود. در مورد string.assign() هم همونطور که در کد نوشتم وقتي بکارببريد که يک آرايه از char داريد و ميخواهيد از متدهاي بدردبخور و کارگشاي std::string استفاده کنيد.


کد: انتخاب همه

#include <string>
#include <fstream>
#include <iostream>

using namespace std;

//Loop through a file reading One-Bye-Per-Cycle
void read_Bytes ( ifstream& ifs )
{
   char c;

   while ( ifs.good() )
      ifs.read(&c, 1);
}
                                                    
//Loop through a file reading One-KilloBye-Per-Cycle
void read_Kbytes ( ifstream& ifs )
{
   char *s = new char[1<<10];

   while ( ifs.good() )
      ifs.read(s, 1<<10);

//Use string.assing(char*) if you need to use string methods
}

//Loop through a text file reading One-Line-Per-Cycle
void read_Lines ( ifstream& ifs )
{
   string str;

   while ( ifs.good() )
      getline ( ifs, str, '\n');
}

typedef void (*FP)(ifstream&);

void run_on_file ( char* filename, FP fp)
{
   ifstream ifs;
   ifs.open( filename );

   (*fp)( ifs );

   ifs.close();
}

void main()
{
   run_on_file ( "c:\\films.txt", read_Bytes );
   run_on_file ( "c:\\films.txt", read_Kbytes );
   run_on_file ( "c:\\films.txt", read_Lines );
}



ارادتمند
نعيمي

ارسال پست

بازگشت به “C Base Programming”