اطلاعیه

Collapse
No announcement yet.

برنامه نویسی به زبان اسمبلی

Collapse
این موضوع برجسته شده است.
X
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    پاسخ : برنامه نویسی به زبان اسمبلی

    نوشته اصلی توسط زوار
    با سلام میشه بگید این میکرو چه عملیاتی را انجام میداد که فقط با اسمبلی میشد بنویسی؟مثلا روتین های محاسباتی زیادی داشت؟
    در میکروکنترلر مذکور در هر ثانیه بیش از صدهزار وقفه اتفاق می افتد که با فرض کلاک 16 مگاهرتز و وجود حلقه اصلی، برای پاسخگویی به هر وقفه کمتر از 160 سیکل زمان وجود دارد که حتی برنامه نویسی اسمبلی به هر شکلی هم جوابگو نیست و برنامه باید بصورت کاملا بهینه و با استفاده از روش ها و دستوراتی که کمترین زمان را صرف می کنند، نوشته شود.

    نوشته اصلی توسط crystalgirl
    با سلام
    یه سوال داشتم در مورد تبدیل کد گری به باینری به زبان اسمبلی.... توو تبدیل باینری به گری راحت میشد برنامه رو نوشت اما برا تبدیل گری به باینری نمی دونم با چه روندی باید کد گری رو با خودش xor کنیم.... از دوستان اگه کسی بتونه کمکم کنه ممنون می شم
    برای تبدیل کد گری به باینری:
    1- بیت با بالاترین ارزش در کد گری به بیت با بالاترین ارزش در کد باینری منتقل می شود.
    2- از سمت چپ به راست و ارزش بالاتر به پائین تر بیت شماره n باینری برابر است با حاصل XOR بیت شماره n در کد گری با بیت شماره n+1 در عدد باینری.
    مثلا اگر بخواهیم 1010 گری را به باینری تبدیل کنیم، در مرحله اول 1xxx برای باینری بدست می آید. سپس 0 بعدی در 1010 را با 1 واقع در 1xxx با هم XOR می کنیم که حاصل 1 می شود. پس عدد باینری تا مرحله 11xx تبدیل می شود. سپس 1 واقع در 1010 را با 1 واقع در 11xx با هم XOR می کنیم تا 110x بدست آید. مرحله آخر هم به همین ترتیب به نتیجه 1100 برای عدد باینری منجر می شود.
    اوژن: به معنای افکننده و شکست دهنده است
    دانایی، توانایی است-Knowledge is POWER
    برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
    وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
    قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
    اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
    ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

    دیدگاه


      پاسخ : برنامه نویسی به زبان اسمبلی

      خیلی ممنون از لطفتون
      اما مشکلی که من دارم مربوط میشه به چگونگی پیاده سازی این روند در اسمبلی

      اگه ممکنه راهنماییم کنید
      تشکر

      دیدگاه


        پاسخ : برنامه نویسی به زبان اسمبلی

        در یک شکل ساده از پیاده سازی روش تبدیل، در برنامه زیر ابتدا یک کپی از R20 در R21 قرار گرفته و بعد بیت شماره 6 از R20 با بیت شماره 7 از R21 با هم XOR شده و حاصل در بیت ششم R21 قرار گرفته است. برای بقیه بیت ها می توانید به همین صورت عمل کنید:
        MOV R21,R20
        BST R21,7
        BLD R16,0
        BST R20,6
        BLD R17,0
        EOR R16,R17
        BST R16,0
        BLD R21,6
        ...
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


          پاسخ : برنامه نویسی به زبان اسمبلی

          نوشته اصلی توسط طراح
          در یک شکل ساده از پیاده سازی روش تبدیل، در برنامه زیر ابتدا یک کپی از R20 در R21 قرار گرفته و بعد بیت شماره 6 از R20 با بیت شماره 7 از R21 با هم XOR شده و حاصل در بیت ششم R21 قرار گرفته است. برای بقیه بیت ها می توانید به همین صورت عمل کنید:
          MOV R21,R20
          BST R21,7
          BLD R16,0
          BST R20,6
          BLD R17,0
          EOR R16,R17
          BST R16,0
          BLD R21,6
          ...


          خیلی ممنون .
          یه سوال! میشه به جای اینکه 8 بار از bst , bld استفاده کنیم, یه loop بذاریم؟

          دیدگاه


            برنامه نویسی به زبان اسمبلی(دستورات انتقال داده)

            سلام من خودم اینها را تازه یاد گرفتم :read: گفتم زکاتشو بدم


            دستورات انتقال داده

            Rr رجیستر مبدا و Rd رجیستر مقصد می باشد.

            دستور MOV
            این دستور رجیستر Rr را در رجیستر Rd کپی می کند.
            mov Rd,Rr

            Rr رجیستر مبدا و Rd رجیستر مقصد می باشد. (یکی از رجیستر های R0 تا R31)


            دستور MOVW
            این دستور دو رجیستر را در دو رجیستر دیگر کپی می کند. الگوی این دستور به صورت زیر است:

            MOVW Rd+1:Rd,Rr+1:Rr

            دستور MOVW را می توان به صورت زیر نیز به کار گرفت:
            MOVW R0,R2
            این دستور نیز محتوای رجیستر R2 و R3 را به ترتیب در رجیستر R0و R1 کپی می کند

            دستور LDI
            این دستور یک مقدار ثابت هشت بیتی را درون فایل رجیستر های R16 تا R31 کپی می کند.
            LDI Rd,K
            K یک مقدار ثابت است.


            دستور LD
            این دستور یک بایت را به صورت غیر مستقیم از فضای داده به درون یک فایل رجیستر کپی می نماید.
            فضای داده می تواند شامل فایل رجیستر ها (R0 تا R31) ،رجیستر I/O ، SRAM باشد
            LD Rd,P
            LD Rd,P+
            LD Rd,-P

            P یکی از رجیستر های X ،Y و Z می باشد
            Rd یکی از رجیستر های R0 تا R31 می باشد
            نکته:(مقدار دهی EEPROM مجزا است )

            دستور LDS
            دستور LDS یک بایت از فضای داده را در یکی از رجیستر های R0 تا R31 کپی می کند

            LDS Rd,K

            K یک مقدار ثابت و به آدرس خانه ای از فضای داده اشاره می کند.
            [hr]
            دستور LDD
            دستور LDD که به آن بارگذاری یا جابه جایی می گویند،مشابه دستور LD به فرم LD با این تفاوت که رجیستر اشاره گر با یک عدد ثابت جمع شده و حاصل آن آدرس اشاره گر جدید را به وجود میاورد.
            LDD Rd,z+q
            LDD Rd,y+q
            q یک مقدار ثابت بین 0تا 63 است.

            ادامه دارد
            یادش بخیر یه وقتایی هر روز میومدم اینجا !

            دیدگاه


              برنامه نویسی به زبان اسمبلی(دستورات انتقال داده)

              ادامه دستورات انتقال داده


              دستور ST
              دستور ST یک بایت را به صورت غیر مستقیم از رجیستر R0 تا R31 به درون فضای داده منتقل می نماید.
              مکان داده توسط رجیستر های اشاره گر X,Y,Z تعیین می شود.
              رجیستر های اشاره گر در حین اجرای دستور ST می توانند بدون تغییر بماند ، کاهش یا افزایش یابند.
              ST P,Rr
              ST P+,Rr
              ST -P,Rr

              P یکی از اشاره گر های X,Y,Z می باشد

              دستور STD
              این دستور که به آن ذخیره یا جابجایی می گویند مشابه دستور ST می باشد.با این تفاوت که رجیستر اشاره گر با یک عدد ثابت جمع شده و حاصل آن آدرس اشاره گر جدید را به وجود می آورد.

              STS y+q,Rr
              STD z+q,Rr

              q یک مقدار ثابت بین 0تا 63 می باشد.
              Rr رجیستر فایل بین R0 تا R31 است.


              دستور IN
              این دستور جهت خواندن از رجیستر های I/O به کار می رود و الگوی آن به صورت زیر است:
              IN Rd,A
              Rd یکی از رجیستر های R0 تا R31 است.
              A آدرس رجیستر مورد نظر در فضای I/O می باشد و بین 0 تا 63 قرار دارد

              مثال:
              کد:
              IN R5,PORTB
              از دستور IN نمی توان برای دستیابی به رجیستر های فضای I/O توصعه یافته استفاده نمود.


              دستور OUT
              دستور OUT مقدار موجود در رجیستر R0تا R31 را روی فضای رجیستر های I/O ذخیره می کند
              OUT A,Rr
              A آدرس رجیستر مورد نظر در فضای I/O میباشد.

              مثال:
              کد:
              OUT DDR,R10


              دستور PUSH
              دستور PUSH ابتدا محتوای فایل رجیستر را در محلی که اشاره گر پشته (STACK POINTER)اشاره می کند (SPH,SPL) ذخیره نموده و سپس اشاره گر پشته یک واحد کاهش می دهد.

              PUSH Rd

              Rd رجیستر فایل بین R0 تا R31 میباشد.


              دستور POP
              این دستور ابتدا اشاره گر پشته را یک واحد افزایش داده و سپس محتوای خانه ای که اشاره گر پشته به آن اشاره
              می کند را در رجیستر فایل Rd ذخیره میکند
              POP Rd

              Rd رجیستر R0 تا R31 است.


              دستور LPM
              از این دستور جهت دستیابی به فضای حاقظه برنامه(FLASH )استفاده می شود.و توسط آن می توان به LOOK UP TABLE دسترسی پیدا نمود.
              LPM Rd,Z

              Z به عنوان آدرس خانه ای از فضای حافظه برنامه می باشد و Rd نیز یکی از رجیستر های R0 تا R31 است.

              دستور LPM تنها معادل LPM R0,Z است .

              جناب طراح این دستور را بیشتر توضیح دادن:
              http://www.eca.ir/forum2/index.php?topic=39020.msg194554#msg194554



              دستور ELPM
              از این دستور جهت دسترسی به فضای برنامه با بیش از 64KB استفاده می شود.
              حافظه های fLASH با بیش از 64KB را می توان در AVR های سری ATMEGA64 به بالا یافت.
              ELPM
              ELPM Rd,z
              ELPM Rd,z+

              دستور SPM
              از این دستور جهت پاک کردن یک صفحه در حافظه برنامه،نوشتن یک صفحه در حافظه و تنظیم بیتهای قفل در بخش BOOT مورد استفاده قرار می گیرد

              [hr]
              اگه اشکالاتی داشت بگین
              یادش بخیر یه وقتایی هر روز میومدم اینجا !

              دیدگاه


                پاسخ : برنامه نویسی به زبان اسمبلی

                نوشته اصلی توسط crystalgirl
                یه سوال! میشه به جای اینکه 8 بار از bst , bld استفاده کنیم, یه loop بذاریم؟
                این زیر برنامه به عنوان مثال تبدیل کد مورد نظر را انجام می دهد و مقدار موجود در R20 را به عدد باینری در R21 تبدیل می کند:

                gray2bin:
                LDI R18,8
                CLT
                LOOP:
                BLD R16,7
                EOR R16,R20
                BST R16,7
                LSL R16
                ROL R21
                LSL R20
                DEC R18
                BRNE LOOP
                RET
                اوژن: به معنای افکننده و شکست دهنده است
                دانایی، توانایی است-Knowledge is POWER
                برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                دیدگاه


                  پاسخ : برنامه نویسی به زبان اسمبلی

                  پیرو سوالی که یکی از دوستان در مورد تبدیل کد gray به باینری انجام دادند، ذکر این مسئله خالی از فایده نیست که برای تبدیل کدها و فراخوانی نتیجه محاسبات مختلف، به غیر از محاسبه مستقیم می توان از روش قرار دادن نتایج مورد نظر در یک Lookup table استفاده کرد. در این روش مهم و پرکاربرد که در زبان های مختلف برنامه نویسی برای میکروکنترلر مورد استفاده دارد، اطلاعات لازم یک بار از قبل محاسبه می شوند و در حافظه Flash میکروکنترلر قرار می گیرند و در زمان اجرای برنامه به سرعت قابل بازیابی می شوند. به عنوان مثال اگر بخواهیم اطلاعات یک شکل موج سینوسی را در برنامه مورد استفاده قرار دهیم، ابتدا یک بار از طریق نرم افزارهای سطح بالا مانند visual basic مقادیر دلخواه را محاسبه می کنیم و اعداد بدست آمده را به شکلی در برنامه قرار می دهیم که موقع پروگرام شدن در flash قرار بگیرند. سپس در هرجایی که لازم باشد این اعداد را فراخوانی می کنیم که این فراخوانی نیازی به محاسبات online برای سینوس را برطرف می کند و مقادیر سینوسی در هنگام اجرای برنامه با سرعت بسیار زیادی قابل دسترس خواهند بود. به عنوان مثالی دیگر می توان مثلا خروجی یک NTC یا PTC را نسبت به دما در نظر گرفت که یک رابطه غیر خطی دارد و این خروجی غیر خطی را می توان در یک جدول قرار داد و در طول برنامه، بدون نیاز به محاسبه از جدول بازیابی کرد. استفاده از این روش در جایی که سرعت اجرا مهم باشد در مواقعی تنها روش ممکن برای رسیدن به نتیجه مورد نظر است. از آنجایی که برنامه نویسی اسمبلی هم در همین موارد سرعت بالاست که توجیه پذیر می شود، بنابراین تسلط بر چگونگی کار با این جدول ها برای یک برنامه نویس اسمبلی از اولویت بالایی برخوردار است.
                  اوژن: به معنای افکننده و شکست دهنده است
                  دانایی، توانایی است-Knowledge is POWER
                  برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                  وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                  قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                  اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                  ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                  دیدگاه


                    پاسخ : برنامه نویسی به زبان اسمبلی

                    در زبان اسمبلی برای AVR همون طور که می دونیم دستور تفریق به شکل sub RD, Rr هستش ....
                    اگه بخوایم با یک رجیستر اشاره گر مثل z عمل تفریق رو انجام بدیم, آیا دستوری مثل sub z, Rd معتبر نیست! پس چاره کار چیه؟

                    دیدگاه


                      پاسخ : برنامه نویسی به زبان اسمبلی

                      اگر منظور کاهش رجیستر 16 بیتی Z به میزان k واحد است که می توانید از دستورات زیر استفاده کنید:

                      SUBI ZL,k
                      SBCI ZH,0


                      روش دوم که بهینه تر است:

                      SBIW ZL,k


                      مقدار k حداکثر می تواند 63 باشد.
                      برای تفاضل رجیستر 16 بیتی Z از یک رجیستر 8 بیتی مثلا R16 می توانید به این صورت عمل کنید:
                      SUB ZL,R16
                      CLR R16
                      SBC ZH,R16

                      اوژن: به معنای افکننده و شکست دهنده است
                      دانایی، توانایی است-Knowledge is POWER
                      برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                      وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                      قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                      اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                      ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                      دیدگاه


                        پاسخ : برنامه نویسی به زبان اسمبلی

                        راستش من دارم یه برنامه می نویسم تحت این عنوان که عدد 16 بیتی واقع در Z به عدد 8 بیتی واقع در R16 تقسیم بشه و خارج قسمت در رجیستر Y و باقی مانده در رجیستر R24 نشون داده بشه.... اما چون در راه حل پیشنهادی شما R16 پاک میشه, من این کارو کردم ( قسمتی از برنامه که با رنگ سبز نوشته شده) آیا درسته؟

                        LDI R29,$ 00
                        LDI R28,$00
                        LDI R15, $FF
                        MOV R17,R16

                        LOOP MOV R16, R17
                        SUB ZL, R16
                        CLR R16
                        SBC ZH , R16
                        INC R28
                        CP R28,R15
                        BRSH LOOP4
                        BREQ LOOP2
                        BRLO LOOP2
                        LOOP2 CP Z, R17
                        BRSH LOOP
                        BREQ LOOP
                        BRLO LPM R24,Z
                        LOOP4 INC R29


                        قسمتهایی هم که با قرمز نوشته شده , قسمتهایی که احتمال میدم اشکال داره!

                        یه سوال در همین راستا : آیا دستور CP Z , R16 معتبره؟

                        دیدگاه


                          پاسخ : برنامه نویسی به زبان اسمبلی

                          در برنامه شما صرف نظر از منظوری که از نوشتن آن دارید، نکات و اشتباهاتی وجود دارد:

                          1- بجای LDI R29,$00 می توانید دستور CLR R29 را بکار ببرید. برای بقیه رجیسترها هم به همین ترتیب است.
                          2- LDI R15,$FF اساسا اشتباه است، چراکه دستور LDI برای R16-R31 قابل استفاده است.
                          3- بعد از هر Label باید علامت : گذاشته شود.
                          4- BRLO LPM R24,Z اشتباه است و احتمالا بخشی از دستور جا افتاده است.
                          5- قرار دادن دو دستور
                          BRSH LOOP4
                          BREQ LOOP2
                          از نظر شکل برنامه نویسی غلط نیست. اما اگر دو مقدار مورد مقایسه برابر باشند، در همان دستور اول پرش انجام می شود و دستور دوم عملا بی فایده است.
                          6- دستور درست CP ZL,R17 است، اما اگر منظور مقایسه Z با دو رجیستر مثلا R17 و R18 باشد، باید بصورت زیر نوشته شود:
                          CP ZL,R17
                          CPC ZH,R18
                          اوژن: به معنای افکننده و شکست دهنده است
                          دانایی، توانایی است-Knowledge is POWER
                          برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                          وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                          قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                          اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                          ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                          دیدگاه


                            پاسخ : برنامه نویسی به زبان اسمبلی

                            نوشته اصلی توسط طراح
                            در برنامه شما صرف نظر از منظوری که از نوشتن آن دارید، نکات و اشتباهاتی وجود دارد:

                            1- بجای LDI R29,$00 می توانید دستور CLR R29 را بکار ببرید. برای بقیه رجیسترها هم به همین ترتیب است.
                            2- LDI R15,$FF اساسا اشتباه است، چراکه دستور LDI برای R16-R31 قابل استفاده است.
                            3- بعد از هر Label باید علامت : گذاشته شود.
                            4- BRLO LPM R24,Z اشتباه است و احتمالا بخشی از دستور جا افتاده است.
                            5- قرار دادن دو دستور
                            BRSH LOOP4
                            BREQ LOOP2
                            از نظر شکل برنامه نویسی غلط نیست. اما اگر دو مقدار مورد مقایسه برابر باشند، در همان دستور اول پرش انجام می شود و دستور دوم عملا بی فایده است.
                            6- دستور درست CP ZL,R17 است، اما اگر منظور مقایسه Z با دو رجیستر مثلا R17 و R18 باشد، باید بصورت زیر نوشته شود:
                            CP ZL,R17
                            CPC ZH,R18
                            خیلی ممنون از راهنماییتون

                            میشه بند 4 رو بیشتر توضیح بدین . متوجه نشدم اشکال BRLO LPM R24,Z کجاست؟
                            یه سوال دیگه! روند برنامه واسه تقسیم 16بیتی بر هشت بیتی درسته؟

                            دیدگاه


                              پاسخ : برنامه نویسی به زبان اسمبلی

                              نوشته اصلی توسط crystalgirl
                              میشه بند 4 رو بیشتر توضیح بدین . متوجه نشدم اشکال BRLO LPM R24,Z کجاست؟
                              یه سوال دیگه! روند برنامه واسه تقسیم 16بیتی بر هشت بیتی درسته؟
                              به عنوان آرگومان دستور BRLO باید یک عدد قرار بگیرد که معمولا یک Label از محلی که لازم است به آن پرش شود، قرار داده می شود و اسمبلر مقدار Label را جایگزین می کند. در مورد الگوریتم تقسیم هم به لینک هایی که در پست های قبل همین تاپیک قرار داده شده مراجعه کنید.
                              اوژن: به معنای افکننده و شکست دهنده است
                              دانایی، توانایی است-Knowledge is POWER
                              برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
                              وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
                              قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
                              اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
                              ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

                              دیدگاه


                                پاسخ : برنامه نویسی به زبان اسمبلی

                                نوشته اصلی توسط طراح
                                به عنوان آرگومان
                                آرگومان یعنی چی؟ :sad: معنی کلی؟
                                توی ویژوال بیسیک 6 آرگومان متغیری بود که هنگام صدا کردن تابع فرستاده میشد.

                                یه منبعی واسه این اصطلاحات هست؟
                                یادش بخیر یه وقتایی هر روز میومدم اینجا !

                                دیدگاه

                                لطفا صبر کنید...
                                X