Con trỏ là con trỏ. Đó là những gì họ đang có. Họ không đối xử khác nhau (bạn có thể đối xử với họ khác nhau như thế nào?)
Sự khác biệt chính giữa X86 và AVR là:
- AVR là 8 bit, X86 là 32 bit (hoặc 64 bit cho x86_64), vì vậy con trỏ có kích thước khác nhau.
- AVR là kiến trúc Harvard được sửa đổi, do đó có nhiều hơn một không gian địa chỉ, vì vậy bạn phải đảm bảo rằng bạn đang tham chiếu đúng không gian địa chỉ.
Ngoài ra, mã của bạn không có ý nghĩa:
char *dir = (void *)0x17;
Gán một khoảng trống * cho một char *?
error: invalid conversion from ‘void*’ to ‘char*’
Hiện tại tôi chưa được thiết lập để biên dịch ATTiny13, vì vậy những con số này đều dành cho ATMega328p:
Truy cập kết quả DDRB và PORTB trong hội đồng này:
12c: 80 e1 ldi r24, 0x10 ; 16
12e: 84 b9 out 0x04, r24 ; 4
130: 85 b9 out 0x05, r24 ; 5
Truy cập một con trỏ đến một vị trí bộ nhớ dẫn đến lắp ráp này:
12c: 80 e1 ldi r24, 0x10 ; 16
12e: 80 93 17 00 sts 0x0017, r24
132: 80 93 18 00 sts 0x0018, r24
Như bạn có thể thấy, DDRB và PORTB không phải là biến thông thường. DDRB được định nghĩa là:
#define DDRB _SFR_IO8(0x04)
và PORTB là:
#define PORTB _SFR_IO8(0x05)
_SFR_IO8 () là một macro:
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
và _MMIO_BYTE là:
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
__SFR_OFFSET có thể là 0 hoặc 0x20 tùy thuộc vào chip (thông thường là 0x20).
Vì vậy, điều đó có nghĩa là địa chỉ của DDRB và PORTB phải lớn hơn 0x20.
Nhìn vào chip 328P, DDRB là 0x04 và PORTB là 0x05. Vì vậy, truy cập dưới dạng 0x24 và 0x25, với các loại dữ liệu phù hợp, do đó:
volatile uint8_t *dir = (volatile uint8_t *)0x24;
volatile uint8_t *port = (volatile uint8_t *)0x25;
*dir = 0x10;
*port = 0x10;
kết quả trong hội nghị này:
12c: 80 e1 ldi r24, 0x10 ; 16
12e: 84 b9 out 0x04, r24 ; 4
130: 85 b9 out 0x05, r24 ; 5
Nhìn có quen không? Trình biên dịch đã nhận ra phần bù 0x20, nhận ra chúng là SFR và được biên dịch theo đúng out
hướng dẫn mà không có phần bù 0x20.
Vì vậy, truy cập địa chỉ cổng của bạn + 0x20 có thể hoạt động cho ATTiny13.
Chỉ cần nhìn vào ATTiny25, DDRB = 0x10
kết quả trong:
out 0x17, r24
và truy cập một con trỏ tại địa chỉ 0x37 dẫn đến:
out 0x17, r24
Vì vậy, có vẻ như nó có thể là nó (thêm 0x20 vào địa chỉ con trỏ của bạn).