2013-04-18 22 views
5

Tôi muốn gây ra một ngoại lệ Hướng dẫn Không xác định ARM Cortex-M3 để kiểm tra thử nghiệm của tôi. Trình biên dịch IAR hỗ trợ điều này với lắp ráp nội tuyến như sau:Lập trình gây ra ngoại lệ Hướng dẫn Không xác định

asm ("udf.w # 0");

Thật không may, trình biên dịch nội tuyến GNU CC không biết mã opcode này cho NXP LPC177x8x. Nó viết chẩn đoán:

ccw3kZ46.s:404: Error: bad instruction `udf.w #0' 

Làm cách nào để tạo một hàm gây ra ngoại lệ Hướng dẫn không xác định?

+0

Theo http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/I1010015.html BLX từ thumb16 không được hỗ trợ bởi M3 và "luôn luôn lỗi". –

Trả lời

7

Xây dựng về câu trả lời Masta79 's:

Có một "vĩnh viễn không xác định" mã hóa được liệt kê trong kiến ​​trúc hướng dẫn tham khảo ARMv7-M - ARM DDI 0403D (documentation placeholder, registration required). Mã hóa là 0xf7fXaXXX (trong đó 'X' bị bỏ qua). Tất nhiên fetches hướng dẫn là ít về cuối nhỏ, vì vậy (không kiểm tra):

asm volatile (".word 0xf7f0a000\n");

nên tạo ra một hướng dẫn xác định được bảo đảm về bất kỳ ARMv7-M hoặc xử lý sau.

+0

Tôi nghĩ anh ấy đang ở chế độ 'thumb'; làm công việc này trong chế độ đó? –

+2

Cortex-M3 chỉ có chế độ Thumb. Đó là tuy nhiên Thumb với Thumb-2 mở rộng, có nghĩa là có cả hai hướng dẫn 16-bit và 32-bit. Các "vĩnh viễn không xác định" một là một 32-bit. – unixsmurf

+1

Tôi không nghĩ bạn nên tự thay đổi người cuối cùng ở đây. Bộ lắp ráp sẽ tự động hoán đổi cho người cuối khi thích hợp. – tangrs

4

Phiên bản thumb-16 của hướng dẫn vĩnh viễn không xác định là 0xDExx. Vì vậy, bạn có thể làm điều này trong mã của bạn để kích hoạt các ngoại lệ:

.short 0xde00 

tham khảo: ARMv7-M Architecture Reference Manual, phần A5.2.6.

(Lưu ý rằng 0xF7Fx, 0xAxxx mã hóa cũng là vĩnh viễn không xác định, nhưng là một hướng dẫn 32-bit).

2

Một số thông tin thêm ...

Một trong GCC của builtins

void __builtin_trap (void)

Chức năng này khiến chương trình thoát bất thường. GCC thực hiện chức năng này bằng cách sử dụng một cơ chế phụ thuộc vào mục tiêu (như cố ý thực hiện một lệnh bất hợp pháp) hoặc bằng cách gọi hủy bỏ. Cơ chế được sử dụng có thể khác nhau từ bản phát hành đến bản phát hành, do đó bạn không nên dựa vào bất kỳ triển khai cụ thể nào.

implementation for ARMv7 is của nó:

(define_insn "trap" 
    [(trap_if (const_int 1) (const_int 0))] 
    "" 
    "* 
    if (TARGET_ARM) 
    return \".inst\\t0xe7f000f0\"; 
    else 
    return \".inst\\t0xdeff\"; 
    " 
    [(set (attr "length") 
    (if_then_else (eq_attr "is_thumb" "yes") 
       (const_int 2) 
       (const_int 4))) 
    (set_attr "type" "trap") 
    (set_attr "conds" "unconditional")] 
) 

Vì vậy, cho ARM chế độ gcc sẽ tạo 0x7f000f0 (f0 00 f0 07) và cho các chế độ khác 0xdeff (ff de) (đi kèm tiện dụng khi tháo/gỡ lỗi).

Also note that:

these encodings match the UDF instruction that is defined in the most 
recent edition of the ARM architecture reference manual. 

Thumb: 0xde00 | imm8 (we chose 0xff for the imm8) 
ARM: 0xe7f000f0 | (imm12 << 8) | imm4 (we chose to use 0 for both imms) 

Đối LLVM__builtin_trap giá trị được tạo ra là 0xe7ffdefe0xdefe:

case ARM::TRAP: { 
    // Non-Darwin binutils don't yet support the "trap" mnemonic. 
    // FIXME: Remove this special case when they do. 
    if (!Subtarget->isTargetDarwin()) { 
    //.long 0xe7ffdefe @ trap 
    uint32_t Val = 0xe7ffdefeUL; 
    OutStreamer.AddComment("trap"); 
    OutStreamer.EmitIntValue(Val, 4); 
    return; 
    } 
    break; 
} 
case ARM::tTRAP: { 
    // Non-Darwin binutils don't yet support the "trap" mnemonic. 
    // FIXME: Remove this special case when they do. 
    if (!Subtarget->isTargetDarwin()) { 
    //.short 57086 @ trap 
    uint16_t Val = 0xdefe; 
    OutStreamer.AddComment("trap"); 
    OutStreamer.EmitIntValue(Val, 2); 
    return; 
    } 
    break; 
} 
2

Có khác nhau hướng dẫn xác định chính thức trong [1] (tìm UDF; . dưới đây có thể được thay thế với bất kỳ chữ số hex nào):

  • 0xe7f...f. - ARM hoặc mã hóa A1 (ARMv4T, ARMv5T, ARMv6, ARMv7)
  • 0xde.. - Thumb hoặc mã hóa T1 (ARMv4T, ARMv5T, ARMv6, ARMv7)
  • 0xf7f.a... - Thumb2 hoặc mã hóa T2 (ARMv6T2, ARMv7)

Có những người khác, nhưng đây có thể là bằng chứng trong tương lai.

Đối tạo mã kích hoạt nó, bạn chỉ có thể sử dụng .short hoặc .word, như thế này:

  • asm volatile (".short 0xde00\n");/* ngón tay cái hướng dẫn bất hợp pháp */
  • asm volatile (".word 0xe7f000f0\n");/* tay hướng dẫn bất hợp pháp */
  • asm volatile (".word 0xe7f0def0\n");/* hướng dẫn bất hợp pháp bằng tay + ngón tay */

Lưu ý rằng người cuối cùng sẽ giải mã e đến 0xdef0, 0xe7f0 trong ngữ cảnh ngón tay cái và do đó cũng gây ra ngoại lệ hướng dẫn không xác định.

[1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.subset.architecture.reference/index.html

+0

Có bất kỳ hương vị nào của ngôn ngữ lắp ráp ARM có thể ghi nhớ cho bất kỳ cách nào trong số này, cách x86 có ['UD2'] (http://www.felixcloutier.com/x86/UD2.html) không? –

+1

Tài liệu ARM tham khảo 'UDF', nhưng tôi không biết liệu đó có được nhận dạng bởi bất kỳ trình biên tập nào không. gcc/gas không nhận ra nó. – domen

+0

Và đối với ARMv8/aarch64/arm64, có 'BRK',' HLT', 'HVC',' SMC' và 'SVC' được ghi trong * C3.1.4 Tạo và trả về ngoại lệ * của DDI0487A (ARM ARM).Không giống như 'vĩnh viễn undefined', nhưng có thể hữu ích. – domen

Các vấn đề liên quan