Bất kỳ lập trình viên lắp ráp 68k nào tốt ngoài đó ?? Tôi đang sử dụng một trình biên dịch Green Hills thương mại cho một Motorola 68040 và tôi thấy một số hành vi rất lạ từ mã. Đôi khi, mã sẽ thực hiện so sánh if/else và lấy chi nhánh sai. Ví dụ:68040 Mất chi nhánh sai nếu người khác
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
Mã đôi khi sẽ d !? Tôi đã phát hiện ra rằng khi xảy ra lỗi này, luôn có một ISR cụ thể làm gián đoạn quá trình so sánh. Tôi đã nhìn vào hội đồng được tạo ra cho ISR và thấy một vài điều không hợp lý với tôi. Đầu tiên nó trông giống như các thanh ghi trạng thái dấu phẩy động, FPSR, FPCR và FPIAR, không được lưu trong ISR. Điều này sẽ giải thích tại sao if/elses đang dùng sai chi nhánh. Thanh ghi FPSR được sử dụng để xác định kết quả của phép so sánh, và nếu thanh ghi đó được ghi đè trong ISR thì nhánh có thể đi sai đường dẫn. Sau đây là xuất nhập cảnh lắp ráp tạo ra bởi trình biên dịch:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
Tôi nhìn qua của Programmer Reference Manual và tôi không thể tìm thấy bất cứ điều gì gợi ý rằng FSAVE, hoặc FMOVEM, tiết kiệm dung thanh ghi trạng FP. Trên thực tế, tôi thấy một bình luận cho thấy rằng nó không, "FSAVE không lưu sổ đăng ký mô hình của lập trình viên của đơn vị dấu chấm động; nó chỉ tiết kiệm phần vô hình của người dùng của máy." Vì vậy, tôi đã thêm một số lắp ráp của riêng tôi để tiết kiệm đi đăng ký tại đầu của ISR, và khôi phục lại chúng ở cuối, và điều này cải thiện đáng kể hiệu suất, nhưng tôi vẫn thấy một số vấn đề. Sau đây là những bổ sung tôi đã thực hiện; các biến dự phòng được nhập là unsigned long trong mã C:
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
FMOVE %FPIAR,fpiar_backup
FMOVE %FPSR,fpsr_backup
FMOVE %FPCR,fpcr_backup
; isr code ...
FMOVE fpiar_backup,%FPIAR
FMOVE fpsr_backup,%FPSR
FMOVE fpcr_backup,%FPCR
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
Tôi đã có một thời gian khó tin rằng trình biên dịch thực sự có lỗi do không lưu sổ đăng ký. Vì vậy, tôi bắt đầu xem xét các giá trị của FPx và Dx để thấy rằng chúng được khôi phục về giá trị thích hợp, và có vẻ như chúng không. Tuy nhiên tôi không phải là 100% mà tôi không làm xáo trộn mã lắp ráp với những sửa đổi của tôi. Sau đây là mã tôi đã thêm để lưu sổ đăng ký; các biến debug được gõ như chờ đợi unsigned:
isr_function:
FMOVE %FP0,debug3
FMOVE %FP1,debug5
FMOVE %FP2,debug7
FMOVE %FP3,debug9
FMOVE %FP4,debug11
FMOVE %FP5,debug13
FMOVE %FP6,debug15
FMOVE %FP7,debug17
FMOVE %FPCR,debug19
FMOVE %FPIAR,debug23
FMOVE %FPSR,debug25
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FMOVE %FP0,debug4
FMOVE %FP1,debug6
FMOVE %FP2,debug8
FMOVE %FP3,debug10
FMOVE %FP4,debug12
FMOVE %FP5,debug14
FMOVE %FP6,debug16
FMOVE %FP7,debug18
FMOVE %FPCR,debug20
FMOVE %FPIAR,debug24
FMOVE %FPSR,debug26
FRESTORE (%SP)+
RTE
Nói tóm lại câu hỏi của tôi là,
1) là có một vấn đề với việc lắp ráp được tạo ra ở chỗ nó không lưu FPSR, FPCR, và thanh ghi FPIAR , và
2) Tôi có lưu đúng các giá trị của thanh ghi khi tôi nhập và thoát ISR không?
Sẽ tuyệt vời nếu tôi có trình biên dịch khác để so sánh. Rất tiếc, tôi không thể đính kèm trình gỡ lỗi vào mã. Tôi có nhiều kinh nghiệm trong C/C++/C#/Java/Python/PHP/v.v., nhưng tôi ở xa một chuyên gia lắp ráp.
Bất kỳ ý tưởng nào được đánh giá cao!
Cảm ơn phản hồi! Tôi không thực sự quan tâm đến việc sử dụng các vị trí bộ nhớ cụ thể. "Tôi sẽ có một chút lo lắng về việc sử dụng các vị trí bộ nhớ cụ thể như fpiar_backup hoặc debug26 trừ khi bạn rất chắc chắn rằng bản thân ISR không dễ bị gián đoạn khác." Các biến đó chỉ được ghi vào trong một ISR đó. Tôi không thấy những tác động bất lợi nào có thể xảy ra. Tôi không chắc chắn về các ưu tiên ngắt, nhưng có thể cho một gián đoạn khác can thiệp. – Samuel
@ user1045004: mối quan tâm của tôi là, nếu xảy ra gián đoạn khác trong khi ISR đó đang chạy, nó có thể ghi đè lên các giá trị. Nó chỉ là một mối quan tâm nếu mã _same_ chạy như vậy, nếu gián đoạn khác là một _different_ một, đó sẽ là okay. – paxdiablo