2010-01-20 28 views
10

Tôi đã gỡ lỗi một số mã C++ (WinCE 6 trên nền tảng ARM), và tôi tìm thấy một số hành vi kỳ lạ:hành vi kỳ lạ của ldr [pc, #VALUE]

4277220C mov   r3, #0x93, 30 
    42772210 str   r3, [sp] 
    42772214 ldr   r3, [pc, #0x69C] 
    42772218 ldr   r2, [pc, #0x694] 
    4277221C mov   r1, #0 
    42772220 ldr   r0, [pc, #0x688] 

Dòng 42772214 ldr r3, [pc, #0x69C] được sử dụng để nhận được một số liên tục từ phần .DATA, ít nhất tôi nghĩ vậy.

Điều lạ lùng theo mã r2 nên được lấp đầy với bộ nhớ từ địa chỉ pc = 0x42772214 + 0x69C = 0x427728B0, nhưng theo nội dung bộ nhớ, nó được tải từ 0x427728B8 (8bytes +), nó cũng xảy ra cho các tập lệnh ldr khác.

Có phải lỗi của trình gỡ rối hoặc sự hiểu biết của tôi về ldr/pc không? Một vấn đề khác mà tôi không nhận được - tại sao truy cập vào phần .data liên quan đến mã được thực thi? Tôi thấy nó hơi lạ.

Và một vấn đề nữa: tôi không thể tìm cú pháp của lệnh mov 1 (bất kỳ ai có thể chỉ cho tôi một đặc điểm kỹ thuật optype cho Thumb (1C2))

Xin lỗi vì sự mô tả người bên lương, nhưng tôi chỉ cần làm quen với các hội đồng.

+0

Điều đó không giống như mã 'thumb', nhưng giống như mã' ARM'.Các địa chỉ của tất cả các lệnh đều cách nhau 4 byte - chỉ có một vài chỉ dẫn 'thumb' 4 byte. –

+0

Trong hầu hết các kiến ​​trúc tôi đã thấy bộ đếm chương trình được tăng lên * trước * lệnh được thực thi. Trong khi thực hiện lệnh, bộ đếm chương trình sẽ chứa địa chỉ của * đầu * của lệnh hiện tại. –

Trả lời

17

Điều này là chính xác. Khi pc được sử dụng để đọc có độ lệch 8 byte ở chế độ ARM và bù đắp 4 byte ở chế độ Ngón tay cái.

Từ ARM-ARM:

Khi một lệnh đọc PC, giá trị đọc phụ thuộc vào hướng dẫn thiết lập nó đến từ:

  • Đối với một lệnh ARM, giá trị đọc là địa chỉ của lệnh cộng 8 byte. Các bit [1: 0] của giá trị này luôn bằng 0, vì các lệnh ARM luôn được căn chỉnh theo từ.
  • Để biết hướng dẫn Thumb, giá trị đọc là địa chỉ của lệnh cộng với 4 byte. Bit [0] của giá trị này luôn bằng 0, bởi vì các lệnh Thumb luôn được căn chỉnh một nửa.

Cách đọc máy tính này chủ yếu được sử dụng để định vị nhanh chóng, vị trí độc lập các hướng dẫn và dữ liệu gần đó, bao gồm phân nhánh độc lập vị trí trong chương trình.

Có 2 lý do để giải quyết vấn đề liên quan đến máy tính.

  1. Mã độc lập vị trí, trong trường hợp của bạn.
  2. Nhận một số hằng số phức tạp gần đó không thể được viết bằng một hướng dẫn đơn giản, ví dụ: mov r3, #0x12345678 không thể hoàn thành trong 1 lệnh, do đó trình biên dịch có thể đặt hằng số này vào cuối hàm và sử dụng ví dụ: ldr r3, [pc, #0x50] để tải nó thay thế.

Tôi không biết những gì mov r3, #0x93, 30 phương tiện. Có lẽ nó là mov r3, #0x93, rol 30 (trong đó cung cấp cho 0xC0000024)?

+3

'mov r3, # 0x93, 30' thực sự có nghĩa là' mov r3, # 0x93, ror 30', cho '0x24c'. –

+1

@Giống như - giải thích tốt và tốt cho việc trích dẫn ARM ARM. Trong đường ống 3 giai đoạn ARM, PC luôn hướng đến lệnh được tìm nạp và PC-4 trỏ tới lệnh được giải mã và PC-8 là "lệnh hiện tại", tức là lệnh đang được thực thi. Đây cũng là lý do tại sao ngoại lệ phải điều chỉnh giá trị LR trước khi trở về. Như bạn đã lưu ý, điều này áp dụng cho các lệnh ARM (32 bit), do đó điều chỉnh 4 byte cho mỗi giai đoạn đường ống. – Dan