هل يتعين على المرء أن يعرف بنية الآلة لكتابة التعليمات البرمجية؟

StackOverflow https://stackoverflow.com/questions/1046068

سؤال

لنفترض أنني أبرمج باستخدام Java أو Python أو C++ لمشكلة بسيطة، قد تكون إنشاء خادم صدى TCP/UDP أو حساب المضروب.هل يجب أن أهتم بتفاصيل البنية، أي إذا كانت 32 أو 64 بت؟

IMHO، ما لم أكن أبرمج شيئًا يتعلق بأشياء منخفضة المستوى إلى حد ما، فلا داعي للقلق إذا كان 32 أو 64 بت.هل أنا على خطأ؟أم أني على حق؟؟؟

هل كانت مفيدة؟

المحلول

الصحيح لمعظم الظروف

سيقوم وقت التشغيل/اللغة/المترجم بتجريد هذه التفاصيل إلا إذا كنت تتعامل مباشرة مع أحجام الكلمات أو الثنائية عند مستوى منخفض.

حتى يتم استخراج الترتيب الثانوي بواسطة مكدس NIC/الشبكة في النواة.وهي مترجمة لك.عند برمجة المقابس في لغة C، يتعين عليك أحيانًا التعامل مع ترتيب البايت للشبكة عند إرسال البيانات ...لكن هذا لا يتعلق باختلافات 32 أو 64 بت.

عند التعامل مع نقاط البيانات الثنائية، فإن تعيينها من بنية إلى أخرى (كتراكب لبنية C على سبيل المثال) يمكن أن يسبب مشاكل كما ذكر الآخرون، ولكن هذا هو السبب وراء قيامنا بتطوير بروتوكولات مستقلة عن البنية تعتمد على الأحرف وما إلى ذلك.

في الواقع، تعمل أشياء مثل Java في جهاز افتراضي يلخص الآلة خطوة أخرى!

معرفة قليلا حول مجموعة التعليمات الخاصة بالبنية، وكيفية تجميع بناء الجملة وفقًا لذلك، يمكن أن يساعدك ذلك على فهم النظام الأساسي وكتابة تعليمات برمجية أكثر وضوحًا وإحكامًا.أعلم أنني أتجهم من بعض أكواد C القديمة بعد دراسة المترجمين!

نصائح أخرى

إن معرفة كيفية عمل الأشياء، سواء كانت كيفية عمل الآلة الافتراضية، أو كيفية عملها على النظام الأساسي الخاص بك، أو كيفية تحويل بنيات C++ معينة إلى تجميع، ستجعلك دائمًا مبرمجًا أفضل، لأنك ستفهم لماذا يجب أن تتم الأشياء بالطريقة التي يجب أن تتم بها. نكون.

أنت بحاجة إلى فهم أشياء مثل الذاكرة لمعرفة ما هي الأخطاء في ذاكرة التخزين المؤقت ولماذا قد تؤثر على برنامجك.يجب أن تعرف كيفية تنفيذ أشياء معينة، على الرغم من أنك قد تستخدم فقط واجهة أو طريقة عالية المستوى للوصول إليها، فإن معرفة كيفية عملها ستضمن أنك تفعل ذلك بأفضل طريقة.

بالنسبة لعمل الحزم، تحتاج إلى فهم كيفية تخزين البيانات على الأنظمة الأساسية وكيف أن إرسالها عبر الشبكة إلى نظام أساسي مختلف قد يغير كيفية قراءة البيانات (endian-ness).

سيحقق المترجم الخاص بك أقصى استفادة من النظام الأساسي الذي تقوم بالتجميع عليه، لذا طالما أنك تلتزم بالمعايير والتعليمات البرمجية جيدًا، يمكنك تجاهل معظم الأشياء وتفترض أن المترجم سيخرج ما هو الأفضل.

باختصار، لا.لا تحتاج إلى معرفة الأشياء ذات المستوى المنخفض، ولكنها لا يضر أن تعرف.

وكانت آخر مرة نظرت إلى المواصفات لغة جافا، فإنه يحتوي على مسكتك مثير للسخرية في القسم الخاص الملاكمة صحيحة.

Integer a = 100;
Integer b = 100;

System.out.println(a == b);

ويضمن ذلك لطباعة true.

Integer a = 300;
Integer b = 300;

System.out.println(a == b);

وهذا ليس مضمونا لطباعة true. ان ذلك يعتمد على وقت التشغيل. المواصفات تركها مفتوحة تماما. انها لالملاكمة عدد صحيح بين -128 و 127 عوائد الأشياء "داخليا" (مشابهة للطريقة التي يعتقل سلسلة حرفية)، ولكن يتم تشجيع المنفذ من وقت تشغيل اللغة لرفع هذا الحد إذا رغبوا في ذلك.

وأنا شخصيا أعتبر أنه قرار مجنون، وآمل انهم ثابتة منذ (الكتابة مرة واحدة، تشغيلها في أي مكان؟)

في بعض الأحيان يجب أن تهتم.

قد تتفاجأ عندما تقفز هذه التفاصيل ذات المستوى المنخفض فجأة وتعضك.على سبيل المثال، جافا موحدة double أن يكون 64 بت.ومع ذلك، يستخدم Linux JVM وضع "الدقة الموسعة"، عندما يكون الضعف 80 بت طالما أنه موجود في سجل وحدة المعالجة المركزية.وهذا يعني أن التعليمات البرمجية التالية قد تفشل:

double x = fun1();
double y = x;

System.out.println(fun2(x));

assert( y == x );

ببساطة لأنه تم إخراج y من السجل إلى الذاكرة وتم اقتطاعه من 80 إلى 64 بت.

في جافا وبيثون، وتستخرج تفاصيل العمارة بعيدا بحيث يكون في الواقع أكثر أو أقل من المستحيل لكتابة التعليمات البرمجية التي تعتمد على الهندسة المعمارية.

ومع C ++، وهذا هو مسألة مختلفة تماما - من المؤكد أننا نستطيع كتابة التعليمات البرمجية التي لا تعتمد على تفاصيل الهندسة المعمارية، ولكن عليك أن تكون حذرا لتجنب المزالق، وتحديدا فيما يتعلق أنواع البيانات الأساسية التي هي تعتمد على الهندسة المعمارية، مثل int .

وطالما أنك تفعل أشياء بشكل صحيح، فأنت لا تكاد تحتاج إلى معرفته لمعظم اللغات. في كثير، فأنت لا تحتاج إلى معرفته، كما لا تختلف سلوك لغة (جافا، على سبيل المثال، تحدد السلوك وقت التشغيل على وجه التحديد).

في C ++ و C، فعل الأشياء بشكل صحيح لا يشمل وضع افتراضات حول كثافة العمليات. لا تضع المؤشرات في كثافة، وعندما كنت تفعل أي شيء مع أحجام الذاكرة أو عناوين استخدام size_t وptrdiff_t. لا تعول على حجم أنواع البيانات: كثافة العمليات يجب أن تكون على الأقل 16 بت، ودائما تقريبا هو 32، ويمكن أن تكون 64 في بعض أبنية. لا تفترض وسيتم ذلك أن الحساب الفاصلة العائمة في بنفس الطريقة تماما على أجهزة مختلفة (معايير IEEE لها بعض الفسحة فيها).

والى حد كبير جميع انظمة التشغيل التي تدعم والشبكات اعطيكم بعض طريقة للتعامل مع المشاكل endianness الممكنة. استخدمهم. استخدام مرافق لغة مثل isalpha () لتصنيف الشخصيات، بدلا من العمليات الحسابية على الحروف (الذي قد يكون شيء غريب مثل EBCDIC). (وبطبيعة الحال، انها الآن أكثر من المعتاد استخدام wchar_t كنوع حرف، وتستخدم Unicode داخليا).

إذا كنت في البرمجة بايثون أو جافا، ومترجم وآلة افتراضية مجردة على التوالي هذه الطبقة من الهندسة المعمارية. ثم كنت بحاجة لا داعي للقلق إذا لم يعمل على العمارة 32 أو 64 بت.

والشيء نفسه لا يمكن أن يقال عن C ++، والتي عليك أن تسأل نفسك بعض الأحيان إذا كنت تقوم بتشغيل على جهاز 32 أو 64 بت

وسوف تحتاج لرعاية حول "endian نيس" فقط إذا قمت بإرسال واستقبال البنيات C الخام عبر السلك مثل

ret = send(socket, &myStruct, sizeof(myStruct));

ولكن هذه ليست الممارسة الموصى بها.

ومن المستحسن أن قمت بتعريف بروتوكول بين الطرفين مثل ذلك لا يهم الأطراف أبنية الجهاز.

في C ++، عليك أن تكون حذرا جدا إذا كنت تريد كتابة التعليمات البرمجية التي تعمل بلا مبالاة على 32 أو 64 بت. كثير من الناس يعتقدون خطأ أن int يمكن تخزين مؤشر، على سبيل المثال.

ومع جافا وصافي لم يكن لديك حقا أن تهتم به إلا إذا كنت تفعل منخفض جدا الاشياء مستوى مثل بت twiddling. إذا كنت تستخدم ج، ج ++، فورتران قد تحصل من قبل ولكن أنصح فعلا باستخدام أشياء مثل "stdint.h" حيث يمكنك استخدام نهائية يعلن مثل uint64_t وuint32_t بحيث تكون واضحة. أيضا، سوف تحتاج إلى بناء مع بخاصة المكتبات اعتمادا على الطريقة التي يتم ربط، على سبيل المثال نظام 64 بت قد تستخدم دول مجلس التعاون الخليجي في الوضع الافتراضي 64 بت ترجمة.

وآلة 32 بت وسوف تسمح لك الحصول على الحد الأقصى من 4 غيغابايت من الذاكرة الظاهرية للتوجيه. (في الواقع، انها حتى أقل من ذلك، وعادة 2 GB أو 3 GB اعتمادا على نظام التشغيل ومختلف الخيارات رابط.) على جهاز 64 بت، هل يمكن أن يكون مساحة ضخمة الظاهري عنوان (في أي معنى عملي، محدود فقط من القرص ) وRAM جميلة كبير لعنة.

وحتى إذا كنت تتوقع مجموعات البيانات 6GB لبعض حساب (دعنا نقول شيئا يحتاج إلى الوصول غير متماسكة ولا يمكن أن يكون مجرد تدفق قليلا في كل مرة)، على هندسة 64 بت هل يمكن أن مجرد قراءتها في ذاكرة الوصول العشوائي والقيام الاشياء الخاصة بك، في حين على الهندسة المعمارية 32 بت تحتاج إلى وسيلة مختلفة جذريا إلى الاقتراب منه، لأنك ببساطة لم يكن لديك خيار حفظ كامل مقيم مجموعة البيانات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top