View Full Version : مشکل در اجرای وقفه در ویندوز 64 بیتی
deopen
چهارشنبه 06 آذر 1387, 12:40 عصر
سلام, من از ویندوز 64بیتی استفاده میکنم , به تازگی اسمبلی رو شروع کردم, کدهایی که مینویسم همیشه در ویندوز 64 بیتی به مشکل بر میخورن, برای مثال برنامه زیر رو با cpp اجرا کردم (وقفه Set cursor position) :
int main() {
int a;
__asm {
mov ah,02h
mov dh,10h
mov dl,40h
int 10h
}
return 0;
}
برنامه به مشکل بر میخوره, مثل اینکه نباید اعداد 16 بیتی رو در رجیسترهای dh و dl بریزم؟!!
Nima_NF
چهارشنبه 06 آذر 1387, 14:33 عصر
در حالت 64bit نمی توان از قابلیت کدنویسی اسمبلی میان کدها (Inline) استفاده کرد. بلکه باید در فایل جداگانه با تمامی دستورات و عنوان و ... در فایل یک فایل asm بنویسید و آن را به صورت cutom build کامپایل کنید که قبلا برایتان توضیح دادم.
البته اگر نوع خروجی را به صورت 32bit کامپایل کنید این امکان asm__ هست.
در حالت 32 بیت، اکثر موارد باید 32 بیت باشد و در حالت 64 بیت نیز رجیستر ها 64 بیت هستند. پس نصف آن می شود 32 بیت.
کلا برنامه نویسی asm 64 بیت متفاوت هست و باید دستورات و رجیستر های آن را از کتاب های آن مطالعه کنید. چرا که برای هر سیستم عامل و اسمبلر به صورت ظاهری متفاوت است.
deopen
چهارشنبه 06 آذر 1387, 14:58 عصر
پس من نمیتونم در فایل cpp اسمبلی بنویسم و باید فایلی جدا با پسوند asm تولید کنم, و در عین حال دستورات 32 بیتی برای 64 بیتی قابل اجرا نیست!! خوب برای 32 بیتی از اعداد هگز استفاده میکردم , در 64 بیتی از چه اعدادی باید استفاده کنم..؟؟!! من فکر میکردم در 64 بیتی هم میشه با روش 32 بیتی برنامه نوشت... !
deopen
چهارشنبه 06 آذر 1387, 15:00 عصر
البته اگر نوع خروجی را به صورت 32bit کامپایل کنید این امکان asm__ هست.
یعنی چی؟؟!!
Nima_NF
پنج شنبه 07 آذر 1387, 13:29 عصر
این می شود یک نمونه برنامه .asm جداگانه:
.686
.model flat
public _fcall
.code
_fcall PROC
push EBP
mov EBP, ESP
; Stores the contents of the i1 variable in the EAX register
mov EAX, DWORD PTR [EBP+8]
sub EAX, DWORD PTR [EBP+12]
call _mul3
pop EBP
ret
_fcall ENDP
_mul3 PROC
mov EBX, 3
imul EBX
ret
_mul3 ENDP
end
در برنامه های 64 بیت باید به شکل فوق برنامه را جدا بنویسید و کامپایل کنید.
در حال 32 بیت، می توانید از منوی build گزینه configuration manager را انتخاب کنید و solution platforms با استفاده از New یک پلتفرم x86 برای 32 بیت انتخاب کنید و بر اسای آن کامپایل کنید.
در این صورت امکان inline وجود دارد.
پس نیاز نیست به ویندوز 32 بیت بروید، فقط برنامه را به صورت 32 کامپایل کنید و در همان ویندوز 64 بیت کار کنید.
یک نمونه در ++visual C:
include<iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int x ;
x = 100 + 5;
_asm{
mov eax, DWORD PTR x
inc eax
mov DWORD PTR x, eax
}
//or use:
/*
_asm{
mov ax, WORD PTR x // 16-bit for AX, 8-bit for AL or AH
inc ax
mov WORD PTR x, eax
}
*/
cout << x;
getchar();
return 0;
}
چیزی که شما در حال نوشتن آن هستید 16 بیت هست.
در هر حال مشکلی که در کدهای شما وجود دارد همان وقفه ها هست یعنی INT نه طول کدهای شما.
من خیلی وقت هست که با اسمبلی کار نکردم، اما تا جایی که اطلاع دارم و در کتاب ها نیز دیدم این وقفه های با INT بیشتر در Dos کاربرد داشتند و در محیط 32 بیت خطای debugger دریافت خواهد شد. و در ویندوز باید از API های ویندوز استفاده کرد.
Jaguar
پنج شنبه 07 آذر 1387, 17:27 عصر
فکر کنم چند چیز با هم قاطی شده باشد. اما اگر درست فهمیده باشم ... برنامه ای که نوشته اید به شکل برنامه های قدیمی 16 بیتی DOS جلوه می کند و نه یک برنامه ی 64 بیتی و فقط شما می خواهید آن را در یک محیط 64 بیتی اجرا کنید. آیا برنامه در محیط 32 بیتی با یک کامپایل 32 بیتی اجرا می شود. به نظر میرسد که از VC استفاده شده است. با این همه تا وقتی که به دستور int 10h نرسیده ایم نباید هیچ اشکالی باشد. در محیط ویندوز و در حالت مد کاریری نمی توانید چنین دسترسی به وقفه 10h بایوس داشه باشید. برای آموزش برنامه نویسی داس باید از یک کامپایلر مربوط آن (مانند کامپایلر های قدیمی مایکروسافت و بورلند) استفاده کنید و بهتر است از یک برنامه ی مقلد داس مانند DOSBOX برای اجرای آن برنامه ها استفاده کنید.
deopen
پنج شنبه 07 آذر 1387, 19:27 عصر
در حال 32 بیت، می توانید از منوی build گزینه configuration manager را انتخاب کنید و solution platforms با استفاده از New یک پلتفرم x86 برای 32 بیت انتخاب کنید و بر اسای آن کامپایل کنید.
پلتفرم کامپایل من در کامپایلرم win32 هست.
در این صورت امکان inline وجود دارد.
من در حال حاظر توانایی استفاده ا کدهای inline رو دارم, اما همانطور که خودتون اشاره کردید :
در هر حال مشکلی که در کدهای شما وجود دارد همان وقفه ها هست یعنی INT نه طول کدهای شما.
مشکل من همینه, و من به تازگی متوجه این مشکل شدم.
در ویندوز باید از API های ویندوز استفاده کرد
API کلمه ای دوست داشتنی ولی هراس انگیز برای من چون من فقط در vb فراخوانیشون کردم , در cpp هم اجراشون کردم ولی چون نمی دونم چرا قبل از فراخوانی توابع اینو مینویسن :
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
روشون کار نکردم, آخه نمیدونم چرا قبل از آرگامونها دقیقا اسم همون آرگامون رو مینویسن!! مثلا HINSTANCE hInstance و چجوری آرگامونهاشون هم اسم مستعارشون تو تابعا!! مثلا HINSTANCE hInstance , جایی مطالعه کردم که اینا استاندارهای مقدار آرگامونن , ولی من نمیتونم از تابعی که اطلاعات کافی ازش ندارم استفاده کنم ! و از همه مهمتر اینکه من فقط با main() کار کردم که نیازی به آرگامون نداره و نمیدونم چرا باید برنامه رو به این طریق بنویسم!! البته من دارم Progamming.Windows.5th.Edition رو مطالعه میکنم ولی بازم این نکات برام مبهمه!!
در eBook کامپایلر fasm هم توصیه به استفاده از API شده, هم در 64 بیتی هم در 32 بیتی ولی من اصلا راجع به اجرای API در اسمبلی چیزی نمیدونم!!
فکر کنم چند چیز با هم قاطی شده باشد. اما اگر درست فهمیده باشم ... برنامه ای که نوشته اید به شکل برنامه های قدیمی 16 بیتی DOS جلوه می کند و نه یک برنامه ی 64 بیتی و فقط شما می خواهید آن را در یک محیط 64 بیتی اجرا کنید. آیا برنامه در محیط 32 بیتی با یک کامپایل 32 بیتی اجرا می شود. به نظر میرسد که از VC استفاده شده است. با این همه تا وقتی که به دستور int 10h نرسیده ایم نباید هیچ اشکالی باشد. در محیط ویندوز و در حالت مد کاریری نمی توانید چنین دسترسی به وقفه 10h بایوس داشه باشید.
شما تمام درخواستهای من رو مختصر و مفید بیان کردید, و پیشنهاد دادید :
برای آموزش برنامه نویسی داس باید از یک کامپایلر مربوط آن (مانند کامپایلر های قدیمی مایکروسافت و بورلند) استفاده کنید و بهتر است از یک برنامه ی مقلد داس مانند DOSBOX برای اجرای آن برنامه ها استفاده کنید.
مرسی من با DOSBOX کار کردم و وقفه هم به درستی اجرا شد.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.