Thông báo

Collapse
No announcement yet.

Xử lý hàm chia của CCS, nguyên dư nuốt tuốt :))

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Xử lý hàm chia của CCS, nguyên dư nuốt tuốt :))

    Em có một hàm như này

    Code:
    Void  LCDwr(int32 num)
    {
       do{
          LCDput('0'+num%10);
          num/=10;
         } while(num);
    }
    Cái dở của nó là em phải dùng phép chia 2 lần. Đã mất thời gian lại tốn ROM.
    Thế là em viết thêm 1 lệnh như này

    Code:
       num/=10;
    rồi cho biên dịch. Kết quả là CCS sinh đoạn mã asm như này

    Code:
    ....................       num/=10; 
    01B4:  BCF    FD8.1
    01B6:  MOVFF  21,2F
    01BA:  MOVFF  20,2E
    01BE:  MOVFF  1F,2D
    01C2:  MOVFF  1E,2C
    01C6:  CLRF   33
    01C8:  CLRF   32
    01CA:  CLRF   31
    01CC:  MOVLW  0A
    01CE:  MOVWF  30
    01D0:  RCALL  0010
    01D2:  MOVFF  03,21
    01D6:  MOVFF  02,20
    01DA:  MOVFF  01,1F
    01DE:  MOVFF  00,1E

    Em định nghĩa thêm một biến như này

    Code:
    int32 inte32;
    #byte inte32=0x00
    ở phần định nghĩa biến chung của chương trình (biến global).
    Thế là em có thể viết lại hàm như này

    Code:
    Void  LCDwrite(int32 num)
    {
       int8  d;
       //
       do{
          d=num%10;
          num=inte32;
          LCDput('0'+d);
         } while(num);
    }


    Đây là đoạn mã asm quan trọng nhất được sinh ra

    Code:
    ....................       d=num%10; 
    0162:  BSF    FD8.1
    0164:  CLRF   FEA
    0166:  MOVLW  23
    0168:  MOVWF  FE9
    016A:  MOVFF  21,2F
    016E:  MOVFF  20,2E
    0172:  MOVFF  1F,2D
    0176:  MOVFF  1E,2C
    017A:  CLRF   33
    017C:  CLRF   32
    017E:  CLRF   31
    0180:  MOVLW  0A
    0182:  MOVWF  30
    0184:  RCALL  0010
    0186:  MOVFF  23,22
    ....................       num=inte32; 
    018A:  MOVFF  03,21
    018E:  MOVFF  02,20
    0192:  MOVFF  01,1F
    0196:  MOVFF  00,1E
    Các bác thử xem sao

  • #2
    Bạn nói rõ hơn nó làm gì không, cái đoạn code
    Code:
    int32 inte32;
    #byte inte32=0x00
    đặt biến inte32 tại địa chỉ 0x00 của RAM, vậy với phép toán này
    Code:
     do{
          d=num%10;
          num=inte32;
          LCDput('0'+d);
         } while(num);
    Liệu có điểm dừng không??
    Diễn đàn Vi điều khiển:

    Comment


    • #3
      Ờ, đọc bài này hôm qua nhưng chả hiểu bác này hỏi về cái gì!

      Comment


      • #4
        Ồi, các bác chán quá , cái này em khoe chứ không phải em hỏi
        Vấn đề là mỗi lần thực hiện chia 2 số unsigned int32, lấy nguyên hoặc lấy dư ('/' hoặc '%') thì PCWHD đều gọi một hàm, chỉ có giá trị trả về là lấy ở 2 biến khác nhau.
        Cái vớ vẩn là ở chỗ em phải thực hiện num%10 rồi ngay sau đó num/10, trong khi đó thì chíp sẽ phải thực hiện 2 việc gần như y xì nhau.
        Hàm div() và ldiv() của PCWHD chỉ hỗ trợ biến có dấu (signed int).
        Và việc em làm là để PCWHD gọi hàm chia 1 lần, trả lại cho mình phần dư, còn phần nguyên thì mình thò tay vào... lấy nốt

        Tóm lại là cái này em muốn tối ưu mã lệnh cho hàm viết một số nguyên không dấu lên LCD, trong hàm trên thiếu 2 lệnh cho con trỏ dịch trái ở đầu hàm và cho con trỏ dịch phải ở cuối hàm (con trỏ DDRAM của LCD nhá).

        Comment


        • #5
          Để hàm tối ưu hơn thì cần một hàm chia số nguyên cho một hằng, hằng ở đây là 10.
          Hôm nay em đã có giải thuật, chỉ dùng lệnh dịch và cộng , nhưng chưa kiểm tra và so sánh với việc dùng lệnh sẵn có của PCWHD nên chưa KHOE với các bác. Để khi nào em kiểm tra xong, kết quả tốt thì em sẽ post.

          Công nhận là hôm nay đọc được một ít về cách giải quyết nhân chia mềm thấy hay thật, rất tuyệt!

          Chip ARM SAM7 cũng không có lệnh nhân cứng các bác ạ

          Comment

          Về tác giả

          Collapse

          KnowMore Tìm hiểu thêm về KnowMore

          Bài viết mới nhất

          Collapse

          Đang tải...
          X