Wow, cảm ơn vì đã gọi cho tôi về điều này. Tôi biết tôi đã thử mã qemu trong http://github.com/dwelch67/yagbat và nghĩ XPUT32 gọi PUT32 theo cách bạn mô tả và nó hoạt động. Nhưng nó KHÔNG xuất hiện để làm việc. Tôi đã tạo ra một số thí nghiệm và khá ngạc nhiên, đây không phải là những gì tôi mong đợi. Bây giờ tôi thấy lý do tại sao gnu linker làm những gì nó làm. Xin lỗi đây là một phản hồi dài nhưng tôi nghĩ nó rất có giá trị. Nó là một chủ đề khó hiểu, tôi biết tôi đã có nó sai trong nhiều năm suy nghĩ pc kéo chế độ bit xung quanh, nhưng nó không.
Trước khi tôi bắt đầu với các thí nghiệm dưới đây, nếu bạn đang đi để làm điều này:
LDR R6, =0x24000
ADD R6, #1 @ (set lsb to 1)
BX R6
vì bạn tình cờ biết rằng 0x24000 là mã ngón tay cái, chỉ cần làm điều này thay vì:
LDR R6, =0x24001
BX R6
Và có, đó là cách bạn chi nhánh để ngón tay cái mã từ cánh tay hoặc ngón tay cái nếu bạn xảy ra để biết rằng địa chỉ hardcoded 0x24000 là một ngón tay cái hướng dẫn bạn bx với một đăng ký có chứa địa chỉ cộng với một.
nếu bạn không biết địa chỉ nhưng biết tên của địa chỉ
ldr r6,=something
bx r6
Những điều tốt đẹp về điều đó là một cái gì đó có thể là một cánh tay hoặc ngón tay cái địa chỉ và mã số trên chỉ hoạt động. Vâng nó hoạt động nếu mối liên kết đúng cách biết những gì loại nhãn đó là cánh tay hoặc ngón tay cái, nếu điều đó được điều sai lầm đó sẽ không làm việc đúng như bạn có thể thấy ở đây
.thumb
ping:
ldr r0,=pong
bx r0
.code 32
pong:
ldr r0,=ping
bx r0
d6008148 <ping>:
d6008148: 4803 ldr r0, [pc, #12] ; (d6008158 <pong+0xc>)
d600814a: 4700 bx r0
d600814c <pong>:
d600814c: e59f0008 ldr r0, [pc, #8] ; d600815c <pong+0x10>
d6008150: e12fff10 bx r0
d6008158: d600814c strle r8, [r0], -ip, asr #2
d600815c: d6008148 strle r8, [r0], -r8, asr #2
rằng didnt pong việc muốn kéo một địa chỉ ngón tay cái từ 0xD600815C nhưng có địa chỉ cánh tay.
đây là tất cả các công cụ lắp ráp gnu btw, cho các công cụ khác bạn có thể phải làm điều gì đó khác. Đối với khí bạn cần phải đặt .thumb_func trước nhãn mà bạn muốn khai báo dưới dạng nhãn ngón tay cái (thuật ngữ hàm func ngụ ý là gây hiểu nhầm, đừng lo lắng về điều gì .thumb_func có nghĩa là nó chỉ là một trò chơi lắp ráp/liên kết).
.thumb
.thumb_func
ping:
ldr r0,=pong
bx r0
.code 32
pong:
ldr r0,=ping
bx r0
và bây giờ chúng ta có được những gì chúng tôi muốn
d6008148 <ping>:
d6008148: 4803 ldr r0, [pc, #12] ; (d6008158 <pong+0xc>)
d600814a: 4700 bx r0
d600814c <pong>:
d600814c: e59f0008 ldr r0, [pc, #8] ; d600815c <pong+0x10>
d6008150: e12fff10 bx r0
d6008158: d600814c strle r8, [r0], -ip, asr #2
d600815c: d6008149 strle r8, [r0], -r9, asr #2
0xD600815C đã lsbit rằng thiết để bạn không cần phải làm bất cứ công việc. Trình biên dịch sẽ xử lý tất cả điều này khi bạn đang thực hiện các cuộc gọi đến các hàm C chẳng hạn. Đối với assembler mặc dù bạn phải sử dụng nó .thumb_func (hoặc một số chỉ thị khác nếu có một) để có được khí để biết đây là một nhãn ngón tay cái và thiết lập các lsbit cho bạn.
Vì vậy, thử nghiệm dưới đây được thực hiện trên một mpcore là ARM11 nhưng tôi cũng đã thử các chức năng testthumb từ 1 đến 4 trên ARM7TDMI và qemu với cùng kết quả.
.globl testarm
testarm:
mov r0,pc
bx lr
armbounce:
mov r0,lr
bx lr
.thumb
.thumb_func
.globl testthumb1
testthumb1:
mov r0,pc
bx lr
nop
nop
nop
bounce:
bx lr
.thumb_func
.globl testthumb2
testthumb2:
mov r2,lr
mov r0,pc
bl bounce
bx r2
nop
nop
nop
.thumb_func
.globl testthumb3
testthumb3:
mov r2,lr
mov lr,pc
mov r0,lr
bx r2
nop
nop
nop
.thumb_func
.globl testthumb4
testthumb4:
push {lr}
ldr r2,=armbounce
mov r1,pc ;@ -4
add r1,#5 ;@ -2
mov lr,r1 ;@ +0
bx r2 ;@ +2
pop {r2} ;@ +4
bx r2
.thumb_func
.globl testthumb5
testthumb5:
push {lr}
ldr r2,=armbounce
mov lr,pc
bx r2
pop {r2}
bx r2
.thumb_func
.globl testthumb6
testthumb6:
push {lr}
bl testthumb6a
.thumb_func
testthumb6a:
mov r0,lr
pop {r2}
bx r2
.thumb_func
.globl testthumb7
testthumb7:
push {lr}
bl armbounce_thumb
pop {r2}
bx r2
.thumb_func
.globl testthumb8
testthumb8:
push {lr}
bl armbounce_thumb_two
pop {r2}
bx r2
.align 4
armbounce_thumb:
ldr r1,[pc]
bx r1
.word armbounce
nop
.align 4
armbounce_thumb_two:
bx pc
nop
.code 32
b armbounce
mà trở nên
d60080b4 <testarm>:
d60080b4: e1a0000f mov r0, pc
d60080b8: e12fff1e bx lr
d60080bc <armbounce>:
d60080bc: e1a0000e mov r0, lr
d60080c0: e12fff1e bx lr
d60080c4 <testthumb1>:
d60080c4: 4678 mov r0, pc
d60080c6: 4770 bx lr
d60080c8: 46c0 nop ; (mov r8, r8)
d60080ca: 46c0 nop ; (mov r8, r8)
d60080cc: 46c0 nop ; (mov r8, r8)
d60080ce <bounce>:
d60080ce: 4770 bx lr
d60080d0 <testthumb2>:
d60080d0: 4672 mov r2, lr
d60080d2: 4678 mov r0, pc
d60080d4: f7ff fffb bl d60080ce <bounce>
d60080d8: 4710 bx r2
d60080da: 46c0 nop ; (mov r8, r8)
d60080dc: 46c0 nop ; (mov r8, r8)
d60080de: 46c0 nop ; (mov r8, r8)
d60080e0 <testthumb3>:
d60080e0: 4672 mov r2, lr
d60080e2: 46fe mov lr, pc
d60080e4: 4670 mov r0, lr
d60080e6: 4710 bx r2
d60080e8: 46c0 nop ; (mov r8, r8)
d60080ea: 46c0 nop ; (mov r8, r8)
d60080ec: 46c0 nop ; (mov r8, r8)
d60080ee <testthumb4>:
d60080ee: b500 push {lr}
d60080f0: 4a15 ldr r2, [pc, #84] ; (d6008148 <armbounce_thumb_two+0x8>)
d60080f2: 4679 mov r1, pc
d60080f4: 3105 adds r1, #5
d60080f6: 468e mov lr, r1
d60080f8: 4710 bx r2
d60080fa: bc04 pop {r2}
d60080fc: 4710 bx r2
d60080fe <testthumb5>:
d60080fe: b500 push {lr}
d6008100: 4a11 ldr r2, [pc, #68] ; (d6008148 <armbounce_thumb_two+0x8>)
d6008102: 46fe mov lr, pc
d6008104: 4710 bx r2
d6008106: bc04 pop {r2}
d6008108: 4710 bx r2
d600810a <testthumb6>:
d600810a: b500 push {lr}
d600810c: f000 f800 bl d6008110 <testthumb6a>
d6008110 <testthumb6a>:
d6008110: 4670 mov r0, lr
d6008112: bc04 pop {r2}
d6008114: 4710 bx r2
d6008116 <testthumb7>:
d6008116: b500 push {lr}
d6008118: f000 f80a bl d6008130 <armbounce_thumb>
d600811c: bc04 pop {r2}
d600811e: 4710 bx r2
d6008120 <testthumb8>:
d6008120: b500 push {lr}
d6008122: f000 f80d bl d6008140 <armbounce_thumb_two>
d6008126: bc04 pop {r2}
d6008128: 4710 bx r2
d600812a: 46c0 nop ; (mov r8, r8)
d600812c: 46c0 nop ; (mov r8, r8)
d600812e: 46c0 nop ; (mov r8, r8)
d6008130 <armbounce_thumb>:
d6008130: 4900 ldr r1, [pc, #0] ; (d6008134 <armbounce_thumb+0x4>)
d6008132: 4708 bx r1
d6008134: d60080bc ; <UNDEFINED> instruction: 0xd60080bc
d6008138: 46c0 nop ; (mov r8, r8)
d600813a: 46c0 nop ; (mov r8, r8)
d600813c: 46c0 nop ; (mov r8, r8)
d600813e: 46c0 nop ; (mov r8, r8)
d6008140 <armbounce_thumb_two>:
d6008140: 4778 bx pc
d6008142: 46c0 nop ; (mov r8, r8)
d6008144: eaffffdc b d60080bc <armbounce>
d6008148: d60080bc ; <UNDEFINED> instruction: 0xd60080bc
d600814c: e1a00000 nop ; (mov r0, r0)
Và kết quả của việc gọi và in tất cả các chức năng
D60080BC testarm
D60080C8 testthumb1
D60080D6 testthumb2
D60080E6 testthumb3
D60080FB testthumb4
testthumb5 crashes
D6008111 testthumb6
D600811D testthumb7
D6008127 testthumb8
Vậy là những gì tất cả điều này làm và những gì nó phải làm với bạn câu hỏi. Điều này phải làm với chế độ hỗn hợp gọi từ chế độ ngón tay cái (và cũng từ cánh tay đơn giản hơn)
Tôi đã lập trình ARM và ngón tay cái ở cấp độ này trong nhiều năm và bằng cách nào đó. Tôi nghĩ rằng chương trình truy cập luôn luôn giữ chế độ trong đó lsbit, tôi biết như bạn biết rằng bạn muốn có nó thiết lập hoặc không được thiết lập khi bạn làm một lệnh bx.
Rất sớm trong mô tả CPU của bộ xử lý ARM trong Cẩm nang tham khảo kiến trúc ARM (nếu bạn đang viết assembly, bạn đã có sẵn điều này, nếu không có thể hầu hết các câu hỏi của bạn sẽ được trả lời).
Program counter Register 15 is the Program Counter (PC). It can be used in most
instructions as a pointer to the instruction which is two instructions after
the instruction being executed...
Vì vậy, hãy kiểm tra và xem điều đó thực sự có ý nghĩa gì, điều đó có nghĩa là trong chế độ cánh tay có hai hướng dẫn, 8 byte phía trước? và ở chế độ ngón tay cái, hai hướng dẫn phía trước hoặc 4 byte phía trước?
Vì vậy, kiểm thử xác minh rằng bộ đếm chương trình là 8 byte phía trước. đó cũng là hai hướng dẫn.
testthumb1 xác minh rằng chương trình là 4 byte phía trước, trong trường hợp này cũng là hai hướng dẫn.
testthumb2
d60080d2: 4678 mov r0, pc
d60080d4: f7ff fffb bl d60080ce <bounce>
d60080d8: 4710 bx r2
nếu bộ đếm chương trình là hai "hướng dẫn" đầu chúng tôi sẽ nhận được 0xD60080D8 nhưng chúng tôi thay vì có được 0xD60080D6 mà là bốn byte phía trước, và có ý nghĩa hơn rất nhiều. Chế độ cánh tay 8 byte phía trước, chế độ ngón tay cái 4 byte phía trước, không gây rối với hướng dẫn giải mã (hoặc dữ liệu) phía trước mã đang được thực thi, chỉ cần thêm 4 hoặc 8.
testthumb3 là một hy vọng rằng mov lr, pc was đặc biệt, nó không phải.
nếu bạn chưa thấy mẫu, bộ lsbit của bộ đếm chương trình KHÔNG được đặt và tôi đoán điều này có ý nghĩa đối với bảng chi nhánh chẳng hạn. Vì vậy, mov lr, pc trong chế độ ngón tay cái KHÔNG thiết lập quyền đăng ký liên kết cho một sự trở lại.
testthumb4 theo một cách rất đau đớn không mất chương trình truy cập bất cứ nơi nào mã này xảy ra với cuối lên và dựa trên hướng dẫn đặt cẩn thận, tính toán địa chỉ trả lại, nếu bạn thay đổi điều đó chuỗi hướng dẫn giữa r1 mov, pc và bx r2 bạn phải trả lại phần bổ sung. Bây giờ, tại sao chúng ta không thể làm một cái gì đó như thế này:
add r1,pc,#1
bx r2
với ngón tay cái bạn có thể, với thumb2 bạn có thể có thể. Và dường như có một số bộ vi xử lý (armv7) hỗ trợ cả lệnh tay và thumb/thumb2, do đó bạn có thể đang ở trong tình huống mà bạn muốn thực hiện, nhưng bạn sẽ không thêm # 1 vì lệnh thumb2 add, nếu có cho phép các thanh ghi phía trên và có ba toán hạng sẽ là một lệnh 4 ngón tay cái 2 byte. (bạn sẽ cần phải thêm # 3).
Vì vậy, testthumb5 là trực tiếp từ mã tôi đã cho bạn thấy rằng dẫn đến một phần của câu hỏi này, và nó bị treo. đây không phải là cách nó hoạt động, xin lỗi tôi lừa dối folks Tôi sẽ cố gắng quay trở lại và vá lên các câu hỏi SO tôi sử dụng này với.
testthumb6 là một thử nghiệm để đảm bảo tất cả chúng ta đều không điên. Tất cả cũng là đăng ký liên kết thực sự có được bộ lsbit để khi bạn bx lr sau đó nó biết chế độ từ bit đó.
testthumb7, điều này có nguồn gốc từ trampoline bên ARM mà bạn thấy trình liên kết làm khi chuyển từ chế độ cánh tay sang chế độ ngón tay cái, trong trường hợp này mặc dù tôi đang chuyển từ chế độ ngón tay sang chế độ cánh tay. tại sao cant linker làm theo cách này? bởi vì trong chế độ ngón tay cái ít nhất bạn phải sử dụng một đăng ký thấp và vào thời điểm này trong trò chơi, sau khi mã được biên dịch các mối liên kết không có cách nào để biết những gì đăng ký nó có thể thùng rác. Trong chế độ cánh tay mặc dù đăng ký ip, không chắc chắn những gì có thể là r12, có thể nhận được thùng rác, tôi đoán nó được dành riêng cho trình biên dịch để sử dụng. Tôi biết trong trường hợp này r1 có thể nhận được thùng rác và sử dụng nó, và điều này hoạt động như mong muốn. mã armbounce được gọi là grabs đăng ký liên kết nếu nơi để quay trở lại, đó là một hướng dẫn ngón tay cái (bộ lsbit) sau khi bl armbounce_thumb trong hàm testthumb7, chính xác nơi chúng ta muốn nó được.
testthumb8 đây là cách trình liên kết gnu thực hiện khi cần chuyển từ chế độ ngón tay cái sang chế độ cánh tay. hướng dẫn bl được thiết lập để đi đến tấm bạt lò xo.sau đó họ làm điều gì đó rất rất phức tạp và điên rồ.
d6008140 <armbounce_thumb_two>:
d6008140: 4778 bx pc
d6008142: 46c0 nop ; (mov r8, r8)
d6008144: eaffffdc b d60080bc <armbounce>
Máy tính bx. Chúng ta biết từ các thí nghiệm ở trên rằng máy tính là bốn byte phía trước, chúng ta cũng biết rằng các lsbit là KHÔNG SET. Vì vậy, điều này nói là chi nhánh cho MÃ ARM đó là bốn byte sau này. Nop là một bộ đệm hai byte, sau đó chúng ta phải tạo ra một lệnh ARM bốn byte phía trước VÀ BẬT TRÊN MỘT BỐN BTENG B ,NG B ,NG, và chúng ta tạo ra một nhánh vô điều kiện cho bất cứ nơi nào chúng ta đang đi, điều này có thể là một cái gì đó hoặc một máy tính ldr , = một cái gì đó tùy thuộc vào cách xa bạn cần phải đi. Rất khôn lanh.
Bản gốc bl arm_bounce_thumb_two thiết lập thanh ghi liên kết để trở về hướng dẫn sau đó bl. Tấm bạt lò xo không thay đổi thanh ghi liên kết nó chỉ thực hiện các nhánh.
nếu bạn muốn để có được chế độ ngón tay cái từ cánh tay sau đó làm những gì mối liên kết thực hiện:
...
bl myfun_from_arm
...
myfun_from_arm:
ldr ip,[pc]
bx ip
.word myfun
mà trông như thế này khi họ làm điều đó (túm lấy từ một nhị phân khác nhau không phải ở 0xD6008xxx nhưng tại 0x0001xxxx).
101f8: eb00003a bl 102e8 <__testthumb1_from_arm>
000102e8 <__testthumb1_from_arm>:
102e8: e59fc000 ldr ip, [pc] ; 102f0 <__testthumb1_from_arm+0x8>
102ec: e12fff1c bx ip
102f0: 00010147 andeq r0, r1, r7, asr #2
vì vậy bất kỳ điều gì đăng ký ip này là (r12?), Chúng không phiền khi truy xuất và tôi cho rằng bạn được tự do chuyển vào thùng rác.
hoàn toàn yêu câu trả lời của bạn và nỗ lực. Nó cũng là những gì tôi đã được chú ý trong firmware này dissasembled tôi đang làm việc trên. Và nó giải thích các sự cố trong thử nghiệm của tôi (không sử dụng trình giả lập .. chỉ cần cập nhật phần mềm điều chế và nạp chip flash ..lol) Phần vững có mã chế độ ARM, ở phần dưới và mã ngón tay cái chỉ dành cho phần ứng dụng chính . Nhưng có, đó là cách nó làm cho ngón tay cái và cánh tay để ngón tay cái. Phần mềm này được biên dịch với ADS v 1.2 btw. – vmanta
Ngoài ra để thêm, như xa tôi có thể nói và như xa như tôi đã đọc, trong chế độ ngón tay cái (ngón tay cái 1 .. nếu theres một điều như vậy) bạn có thể thùng rác R0 - R3, nhưng bạn phải Push/Pop R4 - R7 . Phần vững tôi đang xem xét điều này, và tôi cũng nhận thấy mã từ gcc gnu (arm-elf-gcc) cũng vậy. Vâng .. nó là tuyệt vời bạn đã làm tất cả các bài kiểm tra, bởi vì tôi đã làm tương tự trên thiết bị trong mods phần vững của tôi, nhưng đôi khi tôi nhận được rất bối rối (đặc biệt là khi tai nạn xảy ra do những sai lầm khác) mà tôi resort để sử dụng BL (đau ở mông .... với tính toán bù đắp, như tôi đã giải thích) – vmanta
Tôi sắp viết một chương trình được sử dụng như một bộ tiền xử lý để "làm" và thiết lập bù đắp cho tôi ... có thể sử dụng một số ký hiệu đặc biệt. .. như BL ADR: 0x24000, và prog của tôi để tính toán bù đắp này cho tôi ... ahhh .. đó sẽ là wonderfull .. tại sao không ai nghĩ rằng lol ... có lẽ có một cách mặc dù, tôi chỉ không biết nó được nêu ra .. và nếu có một cách tôi cho rằng nó sẽ là một số loại chỉ thị trong linker .. không biết nhưng tôi đọc và đọc .. đã dành quá nhiều thời gian. Hey cảm ơn rất nhiều người ... và vui vì bạn đã tìm được TRUTH .. hehe – vmanta