X86 অ্যাসেম্বলিতে রেজিস্টারগুলিতে ব্যবহৃত পুশ / পপ নির্দেশাবলীর কাজ কী?


101

এসেম্বলারের বিষয়ে পড়ার সময় আমি প্রায়শই লোকদের কাছে এসে লিখি যে তারা প্রসেসরের একটি নির্দিষ্ট রেজিস্ট্রার চাপ দেয় এবং এটি পূর্বের অবস্থার পুনরুদ্ধার করতে পরে এটিকে আবার পপ করে।

  • আপনি কিভাবে একটি রেজিস্টার ঠেলাতে পারেন? এটি কোথায় ঠেলাঠেলি করা হয়? কেন এটি প্রয়োজন?
  • এটি কি একক প্রসেসরের নির্দেশে ফোটায় বা আরও জটিল?

4
সতর্কতা: সমস্ত বর্তমান উত্তর ইন্টেলের সমাবেশ সিনট্যাক্সে দেওয়া হয়েছে; উদাহরণস্বরূপ যেমন AT & T সিনট্যাক্স মধ্যে ধাক্কা-পপ মত একটি পোস্ট-ফিক্স ব্যবহার b, w, l, অথবা qমেমরি আকার কাজে ব্যবহৃত হচ্ছে বোঝাতে। প্রাক্তন: pushl %eaxএবংpopl %eax
হক্কেন

4
@ হাওকেন বেশিরভাগ সমাবেশে এটিএন্ডটি সিনট্যাক্স (উল্লেখযোগ্যভাবে গ্যাস) গিলে ফেলতে সক্ষম হয়ে অপারেন্ডের আকার থেকে অপারেন্ডের আকার বাদ দিতে পারলে আকারের পোস্টফিক্স বাদ দেওয়া যেতে পারে। আপনার দেওয়া উদাহরণগুলির ক্ষেত্রে এটি হ'ল %eaxসর্বদা আকারে 32 বিট।
গুন্থার পাইজ

উত্তর:


153

একটি মান চাপানো (অগত্যা একটি নিবন্ধে সংরক্ষণ করা নয়) এর অর্থ এটি স্ট্যাকে লেখা writing

পপিং মানে স্ট্যাকের উপরে যা আছে তা পুনরুদ্ধারে একটি পুনরুদ্ধার করা । সেগুলি মৌলিক নির্দেশাবলী:

push 0xdeadbeef      ; push a value to the stack
pop eax              ; eax is now 0xdeadbeef

; swap contents of registers
push eax
mov eax, ebx
pop ebx

4
পুশ এবং পপের জন্য সুস্পষ্ট অপারেন্ডটি r/mকেবল নিবন্ধভুক্ত নয়, তাই আপনিও পারেন push dword [esi]। বা এমনকি pop dword [esp]লোড এবং একই মান একই ঠিকানায় ফিরে সংরক্ষণ করতে। ( github.com/HJLebbink/asm-dude/wiki/POP )। আমি কেবল এটি উল্লেখ করেছি কারণ আপনি "অগত্যা একটি রেজিস্টার" বলছেন না।
পিটার কর্ডস

4
আপনি popমেমরির একটি pop [0xdeadbeef]
এসএস আন

হাই, এখানে পুশ / পপ এবং পুশক / পপকীর মধ্যে পার্থক্য কী? আমি ম্যাকোস / ইন্টেলে আছি
স্টেকওভারফ্লো

46

এখানে আপনি কীভাবে একটি রেজিস্টার ঠেলাবেন। আমি ধরে নিই আমরা x86 এর কথা বলছি।

push ebx
push eax

এটি স্ট্যাকের উপর চাপ দেওয়া হয়। মান ESPরেজিস্টার ধাক্কা মূল্যের আকার decremented যেমন স্ট্যাক এক্স 86 সিস্টেমের মধ্যে কৃত বৃদ্ধি করা হয়।

মূল্যবোধ সংরক্ষণের জন্য এটি প্রয়োজন। সাধারণ ব্যবহার হয়

push eax           ;   preserve the value of eax
call some_method   ;   some method is called which will put return value in eax
mov  edx, eax      ;    move the return value to edx
pop  eax           ;    restore original eax

pushx86 এর একটি একক নির্দেশ যা অভ্যন্তরীণভাবে দুটি কাজ করে।

  1. ESPধাক্কা মানের আকার দ্বারা নিবন্ধকে হ্রাস করুন ।
  2. ESPরেজিস্টারের বর্তমান ঠিকানায় পুশ করা মান সংরক্ষণ করুন ।

@ ওয়াভান কেবল এটি ঠিক করার জন্য একটি অনুরোধ প্রেরণ করেছেন
jgh মজা করুন

38

এটি কোথায় ঠেলাঠেলি করা হয়?

esp - 4। আরো স্পষ্ট করে:

  • esp 4 দ্বারা বিয়োগ করা হয়
  • মান ধাক্কা হয় esp

pop এই বিপরীত।

সিস্টেম ভি এবিআই লিনাক্সকে rspপ্রোগ্রামটি চালু হওয়ার সাথে সাথে একটি সংবেদনশীল স্ট্যাকের অবস্থানের দিকে নির্দেশ করতে বলে : প্রোগ্রাম যখন চালু হয় তখন (ডিএসএম, লিনাক্স) ডিফল্ট রেজিস্ট্রার স্টেটটি কী? যা আপনার সাধারণত ব্যবহার করা উচিত।

আপনি কিভাবে একটি রেজিস্টার ঠেলাতে পারেন?

ন্যূনতম জিএনইউ জিএএস উদাহরণ:

.data
    /* .long takes 4 bytes each. */
    val1:
        /* Store bytes 0x 01 00 00 00 here. */
        .long 1
    val2:
        /* 0x 02 00 00 00 */
        .long 2
.text
    /* Make esp point to the address of val2.
     * Unusual, but totally possible. */
    mov $val2, %esp

    /* eax = 3 */
    mov $3, %ea 

    push %eax
    /*
    Outcome:
    - esp == val1
    - val1 == 3
    esp was changed to point to val1,
    and then val1 was modified.
    */

    pop %ebx
    /*
    Outcome:
    - esp == &val2
    - ebx == 3
    Inverses push: ebx gets the value of val1 (first)
    and then esp is increased back to point to val2.
    */

উপরের গিটহাবের উপর চলমান অ্যাসেসরেন্স সহ

কেন এটি প্রয়োজন?

এটা সত্য যে এই নির্দেশাবলী সহজেই প্রয়োগ করা যেতে পারে mov, addএবং sub

তাদের অস্তিত্বের কারণ, এই যে নির্দেশাবলীর সংমিশ্রণগুলি এত ঘন ঘন হয়, সেই জন্য ইন্টেল সেগুলি আমাদের জন্য সরবরাহ করার সিদ্ধান্ত নিয়েছিল।

এই সংমিশ্রণগুলি এত ঘন ঘন হওয়ার কারণ হ'ল এগুলি নিবন্ধের মানগুলি অস্থায়ীভাবে মেমরিতে সংরক্ষণ এবং পুনরুদ্ধার করা সহজ করে যাতে তারা ওভাররাইট না করে।

সমস্যাটি বুঝতে, কয়েকটি সি কোড হাতে হাতে সংকলনের চেষ্টা করুন।

একটি বড় অসুবিধা হ'ল প্রতিটি ভেরিয়েবলটি কোথায় সংরক্ষণ করা হবে তা সিদ্ধান্ত নেওয়া।

আদর্শভাবে, সমস্ত ভেরিয়েবলগুলি নিবন্ধগুলিতে ফিট হবে যা অ্যাক্সেসের জন্য দ্রুততম মেমরি (বর্তমানে র‌্যামের চেয়ে প্রায় 100x দ্রুত )।

তবে অবশ্যই, আমরা সহজেই নিবন্ধগুলির তুলনায় আরও পরিবর্তনশীল থাকতে পারি, বিশেষ করে নেস্টেড ফাংশনগুলির যুক্তিগুলির জন্য, সুতরাং মেমোরিতে লেখার একমাত্র সমাধান।

আমরা যে কোনও স্মৃতি ঠিকানায় লিখতে পারি, তবে যেহেতু ফাংশন কল এবং রিটার্নের স্থানীয় ভেরিয়েবল এবং তর্কগুলি একটি দুর্দান্ত স্ট্যাক প্যাটার্নে ফিট করে, যা মেমরির খণ্ডন রোধ করে , এটিই এর মোকাবেলার সেরা উপায়। একটি হিপ বরাদ্দ লেখার উন্মাদতার সাথে এর তুলনা করুন।

তারপরে আমরা সংকলকগণকে আমাদের জন্য রেজিস্টার বরাদ্দ অনুকূলিত করতে দাও, যেহেতু এটি এনপি সম্পূর্ণ, এবং সংকলক লেখার সবচেয়ে শক্ত অংশগুলির মধ্যে একটি। এই সমস্যাটিকে রেজিস্টার বরাদ্দ বলা হয় , এবং এটি গ্রাফের বর্ণের থেকে বিচ্ছিন্ন

যখন সংকলকটির বরাদ্দকারী কেবল নিবন্ধের পরিবর্তে জিনিসগুলিকে মেমরিতে সঞ্চয় করতে বাধ্য করা হয়, এটি একটি স্পিল হিসাবে পরিচিত ।

এটি কি একক প্রসেসরের নির্দেশে ফোটায় বা আরও জটিল?

আমরা নিশ্চিতভাবে যা জানি তা হ'ল ইন্টেল একটি pushএবং একটি popনির্দেশকে দলিল করে , সুতরাং সেগুলি সেই দিক থেকে একটি নির্দেশ।

অভ্যন্তরীণভাবে, এটি একাধিক মাইক্রোকোডে প্রসারিত হতে পারে, একটি পরিবর্তন করতে espএবং একটিতে মেমরি আইও করতে এবং একাধিক চক্র গ্রহণ করতে পারে।

তবে এটি আরও সম্ভাব্য যে কোনও একক pushঅন্যান্য নির্দেশাবলীর সমতুল্য সংমিশ্রণের চেয়েও দ্রুত, কারণ এটি আরও নির্দিষ্ট।

এটি বেশিরভাগই আন (ডার) নথিভুক্ত:


4
উফগুলিতে কীভাবে push/ popডিকোড করা হবে সে সম্পর্কে আপনাকে অনুমান করার দরকার নেই। পারফরম্যান্স কাউন্টারগুলিকে ধন্যবাদ, পরীক্ষামূলক পরীক্ষা করা সম্ভব এবং আগ্নার ফগ এটি করেছে এবং নির্দেশ সারণী প্রকাশ করেছে । পেন্টিয়াম-এম এবং পরবর্তী সিপিইউগুলিতে স্ট্যাক ইঞ্জিনের জন্য সিঙ্গল-ইউওপ push/ popধন্যবাদ রয়েছে (অ্যাগনারের মাইক্রোয়ার্ক পিডিএফ দেখুন)। এর মধ্যে সাম্প্রতিক এএমডি সিপিইউ অন্তর্ভুক্ত রয়েছে, ইন্টেল / এএমডি পেটেন্ট-শেয়ারিং চুক্তির জন্য ধন্যবাদ।
পিটার কর্ডেস

@ পিটারকর্ডস দুর্দান্ত! সুতরাং পারফরম্যান্স কাউন্টারগুলি মাইক্রো-অপারেশনগুলি গণনা করতে ইন্টেল দ্বারা নথিভুক্ত হয়?
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

এছাড়াও, রেগস থেকে ছিটানো স্থানীয় ভেরিয়েবলগুলি সাধারণত L1 ক্যাশে এখনও গরম থাকবে যদি সেগুলির মধ্যে আসলে কোনও ব্যবহার হয়। তবে একটি রেজিস্টার থেকে পড়া কার্যকরভাবে বিনামূল্যে, শূন্যে বিলম্বিত। সুতরাং আপনি কীভাবে শর্তাদি সংজ্ঞায়িত করতে চান তার উপর নির্ভর করে এটি L1 ক্যাশের চেয়ে অসীম দ্রুত। কেবল পঠনযোগ্য স্থানীয় লোকদের জন্য স্ট্যাকের মধ্যে ছড়িয়ে পড়ার জন্য, মূল ব্যয় হ'ল অতিরিক্ত লোড উফস (কখনও কখনও মেমরি অপারেশনস, কখনও কখনও পৃথক movলোড সহ)। স্পিলড নন-কনস্টেবল ভেরিয়েবলের জন্য, স্টোর-ফরোয়ার্ডিং রাউন্ড ট্রিপগুলি অতিরিক্ত অতিরিক্ত বিলম্বিতা (অতিরিক্ত extra 5c বনাম বনাম সরাসরি ফরোয়ার্ডিং, এবং স্টোর নির্দেশাবলী সস্তা নয়)।
পিটার কর্ডেস

হ্যাঁ, কয়েকটি ভিন্ন পাইপলাইন পর্যায়ে মোট উফসের কাউন্টার রয়েছে (ইস্যু / এক্সিকিউট / রিটায়ার), যাতে আপনি ফিউজড-ডোমেন বা অব্যবহৃত-ডোমেন গণনা করতে পারেন। উদাহরণস্বরূপ এই উত্তরটি দেখুন । আমি যদি এখন সেই উত্তরটি পুনরায় লিখতে থাকি, ocperf.pyতবে কাউন্টারগুলির জন্য সহজ প্রতীকী নামগুলি ব্যবহার করতে আমি মোড়ক স্ক্রিপ্টটি ব্যবহার করতাম ।
পিটার কর্ডেস

23

পুশিং এবং পপিং রেজিস্টারগুলি এর সমান পর্দার পিছনে রয়েছে:

push reg   <= same as =>      sub  $8,%rsp        # subtract 8 from rsp
                              mov  reg,(%rsp)     # store, using rsp as the address

pop  reg    <= same as=>      mov  (%rsp),reg     # load, using rsp as the address
                              add  $8,%rsp        # add 8 to the rsp

নোট করুন এটি x86-64 এ & টি সিনট্যাক্স নয়।

জুড়ি হিসাবে ব্যবহৃত, এটি আপনাকে স্ট্যাকের মধ্যে একটি রেজিস্টার সংরক্ষণ করতে এবং পরে এটি পুনরুদ্ধার করতে দেয়। এছাড়াও অন্যান্য ব্যবহার আছে।


4
হ্যাঁ, এই ক্রমগুলি সঠিকভাবে পুশ / পপ অনুকরণ করে। (পুশ / পপ ব্যতীত পতাকাগুলি প্রভাবিত করে না)।
পিটার কর্ডস

4
আপনি ভাল ব্যবহার করতে চাই lea rsp, [rsp±8]পরিবর্তে add/ subভাল প্রভাব অনুকরণ push/ popপতাকা করেন।
Ruslan

12

প্রায় সমস্ত সিপিইউ স্ট্যাক ব্যবহার করে। প্রোগ্রামটির স্ট্যাকটি হল হার্ডওয়্যার সমর্থিত পরিচালিত লাইফো কৌশল।

স্ট্যাক হ'ল প্রোগ্রাম (র‌্যাম) মেমরির পরিমাণ সাধারণত সিপিইউ মেমরি হিপের শীর্ষে বরাদ্দ হয় এবং বড় হয় (পুশ নির্দেশে স্ট্যাক পয়েন্টার হ্রাস হয়) বিপরীত দিকে। স্ট্যাকের মধ্যে প্রবেশের জন্য একটি স্ট্যান্ডার্ড শব্দটি পুশ এবং স্ট্যাক থেকে অপসারণের জন্য পিওপি

স্ট্যাকটি স্ট্যাক উদ্দেশ্যে সিপিইউ রেজিস্ট্রারের মাধ্যমে পরিচালিত হয়, যাকে স্ট্যাক পয়েন্টারও বলা হয়, সুতরাং সিপিইউ যখন পিওপি বা পুশ সঞ্চালন করে তখন স্ট্যাক পয়েন্টার একটি রেজিস্টার লোড / স্টোর করে স্ট্যাক মেমোরিতে রাখবে এবং স্ট্যাক পয়েন্টারটি স্বয়ংক্রিয়ভাবে হ্রাসপ্রাপ্ত শূন্যপদযুক্ত শব্দটির সংখ্যা অনুসারে বৃদ্ধি পাবে বা (থেকে) স্ট্যাকের মধ্যে পপ করা।

সমাবেশী নির্দেশাবলী মাধ্যমে আমরা স্ট্যাক করতে সঞ্চয় করতে পারি:

  1. সিপিইউ নিবন্ধন করে এবং স্থির হয়।
  2. ফাংশন বা পদ্ধতির জন্য ঠিকানাগুলি ফেরত দিন
  3. ভেরিয়েবলের মধ্যে / কার্যবিধি
  4. ফাংশন / পদ্ধতি স্থানীয় ভেরিয়েবল।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.