Câu trả lời của CesarB và Pavel cung cấp các trích dẫn từ AAPCS, nhưng vẫn còn các vấn đề mở. Callee có tiết kiệm r9 không? Điều gì về r12? Điều gì về r14? Hơn nữa, các câu trả lời là rất chung chung, và không cụ thể cho chuỗi công cụ arm-eabi theo yêu cầu. Dưới đây là một cách tiếp cận thực tế để tìm ra đăng ký nào được lưu trữ và không được đăng ký.
Mã C sau chứa một khối lắp ráp nội tuyến, yêu cầu sửa đổi thanh ghi r0-r12 và r14. Trình biên dịch sẽ tạo mã để lưu các thanh ghi được yêu cầu bởi ABI.
void foo() {
asm volatile ("nop" : : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r14");
}
Sử dụng dòng lệnh arm-eabi-gcc-4.7 -O2 -S -o - foo.c
và thêm thiết bị chuyển mạch cho nền tảng của bạn (chẳng hạn như -mcpu=arm7tdmi
ví dụ). Lệnh sẽ in mã assembly được tạo trên STDOUT. Nó có thể trông giống như sau:
foo:
stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
nop
ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
bx lr
Lưu ý rằng trình biên dịch tạo mã tiết kiệm và khôi phục r4-r11. Trình biên dịch không lưu r0-r3, r12. Rằng nó khôi phục r14 (bí danh lr) hoàn toàn ngẫu nhiên như tôi biết từ kinh nghiệm rằng mã thoát cũng có thể tải lr đã lưu vào r0 và sau đó làm một "bx r0" thay vì "bx lr". Hoặc bằng cách thêm -mcpu=arm7tdmi -mno-thumb-interwork
hoặc bằng cách sử dụng -mcpu=cortex-m4 -mthumb
chúng tôi có được mã lắp ráp hơi khác nhau trông như thế này:
foo:
stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
nop
ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
Một lần nữa, R4-R11 được lưu và phục hồi. Nhưng r14 (bí danh lr) không được phục hồi.
Để tóm tắt:
- r0-r3 là không callee-lưu
- R4-R11 là callee-lưu
- r12 (bí danh ip) là không callee-lưu
- r13 (bí danh sp) được lưu lại một cách thoải mái
- r14 (bí danh lr) là không callee-saved
- R15 (bí danh pc) là chương trình truy cập và được thiết lập với giá trị của lr trước khi chức năng gọi
này nắm giữ ít nhất là cho mặc định cánh tay-EABI-gcc của của. Có các công tắc dòng lệnh (đặc biệt là công tắc -mabi) có thể ảnh hưởng đến kết quả.
Đây là liên kết bên ngoài có thể hữu ích. [APCS giới thiệu] (http://www.heyrick.co.uk/assembler/apcsintro.html), đặc biệt là một số [tên khác nhau] (http://sourceware.org/ml/binutils/2000-06/msg00240.html) để sử dụng 'register'. –