📄 sd_lib.lss
字号:
if(ok==SD_FAIL)return SD_FAIL;
5c4: 81 30 cpi r24, 0x01 ; 1
5c6: 39 f0 breq .+14 ; 0x5d6 <ReadMBR+0x1e>
if(MBR->MBR_Signature!=0xAA55)return SD_FAIL; //读有效标志,55AA????(网上资料所给)
5c8: 80 91 b0 02 lds r24, 0x02B0
5cc: 90 91 b1 02 lds r25, 0x02B1
5d0: 85 55 subi r24, 0x55 ; 85
5d2: 9a 4a sbci r25, 0xAA ; 170
5d4: 19 f0 breq .+6 ; 0x5dc <ReadMBR+0x24>
5d6: 81 e0 ldi r24, 0x01 ; 1
5d8: 90 e0 ldi r25, 0x00 ; 0
5da: 08 95 ret
//获取参数
PB_RelativeSector=MBR->MBR_pb[0].PB_RelativeSector;//读逻辑地址与绝对地址的偏移
5dc: 80 91 78 02 lds r24, 0x0278
5e0: 80 93 b4 02 sts 0x02B4, r24
return SD_SUCC;
5e4: 80 e0 ldi r24, 0x00 ; 0
5e6: 90 e0 ldi r25, 0x00 ; 0
}
5e8: 08 95 ret
000005ea <ReadBPB>:
//-------------------------------------------------------------------------
uint8_t ReadBPB(void){ //读取BPB数据结构,共4字节
uint8_t ok;
FAT_BPB * BPB=(FAT_BPB*)BUFFER;
ok=ReadFatBlock(FAT_Sector);
5ea: 60 e0 ldi r22, 0x00 ; 0
5ec: 70 e0 ldi r23, 0x00 ; 0
5ee: 80 e0 ldi r24, 0x00 ; 0
5f0: 90 e0 ldi r25, 0x00 ; 0
5f2: 0e 94 9c 02 call 0x538 <ReadFatBlock>
if(ok==SD_FAIL)return SD_FAIL;
5f6: 81 30 cpi r24, 0x01 ; 1
5f8: 19 f4 brne .+6 ; 0x600 <ReadBPB+0x16>
5fa: 81 e0 ldi r24, 0x01 ; 1
5fc: 90 e0 ldi r25, 0x00 ; 0
5fe: 08 95 ret
//获取参数,从512的结构体中获取信息
BPB_BytesPerSec = BPB->BPB_BytesPerSec;//每扇区的字节数,一般为512
600: 80 91 bd 00 lds r24, 0x00BD
604: 90 91 be 00 lds r25, 0x00BE
608: 90 93 af 00 sts 0x00AF, r25
60c: 80 93 ae 00 sts 0x00AE, r24
BPB_SecPerClus = BPB->BPB_SecPerClus;//每簇扇区数,一般为8
610: 80 91 bf 00 lds r24, 0x00BF
614: 80 93 a4 00 sts 0x00A4, r24
BPB_RsvdSecCnt = BPB->BPB_RsvdSecCnt;//保留扇区数,一般为2
618: 80 91 c0 00 lds r24, 0x00C0
61c: 90 91 c1 00 lds r25, 0x00C1
620: 90 93 b3 02 sts 0x02B3, r25
624: 80 93 b2 02 sts 0x02B2, r24
BPB_NumFATs = BPB->BPB_NumFATs;//FAT 表数目,一般为2
628: 80 91 c2 00 lds r24, 0x00C2
62c: 80 93 ab 00 sts 0x00AB, r24
BPB_RootEntCnt = BPB->BPB_RootEntCnt;//根目录区的目录项数,来计算根目录的扇区数
630: 80 91 c3 00 lds r24, 0x00C3
634: 90 91 c4 00 lds r25, 0x00C4
638: 90 93 a6 00 sts 0x00A6, r25
63c: 80 93 a5 00 sts 0x00A5, r24
BPB_TotSec16 = BPB->BPB_TotSec16;//总扇区数
640: 80 91 c5 00 lds r24, 0x00C5
644: 90 91 c6 00 lds r25, 0x00C6
648: 90 93 b1 00 sts 0x00B1, r25
64c: 80 93 b0 00 sts 0x00B0, r24
BPB_FATSz16 = BPB->BPB_FATSz16;//FAT 表所占的扇区数, 以16 位表示,这里一般一个表242项,每项4B,这样242*4/512=2个
650: 80 91 c8 00 lds r24, 0x00C8
654: 90 91 c9 00 lds r25, 0x00C9
658: 90 93 ad 00 sts 0x00AD, r25
65c: 80 93 ac 00 sts 0x00AC, r24
BPB_HiddSec = BPB->BPB_HiddSec;//隐藏扇区数,一般为0
660: 80 91 ce 00 lds r24, 0x00CE
664: 90 91 cf 00 lds r25, 0x00CF
668: a0 91 d0 00 lds r26, 0x00D0
66c: b0 91 d1 00 lds r27, 0x00D1
670: 80 93 a7 00 sts 0x00A7, r24
674: 90 93 a8 00 sts 0x00A8, r25
678: a0 93 a9 00 sts 0x00A9, r26
67c: b0 93 aa 00 sts 0x00AA, r27
return SD_SUCC;
680: 80 e0 ldi r24, 0x00 ; 0
682: 90 e0 ldi r25, 0x00 ; 0
}
684: 08 95 ret
00000686 <DirStartSec>:
//-------------------------------------------------------------------------
uint32_t DirStartSec(void){ //获取根目录开始扇区号
return BPB_RsvdSecCnt+BPB_NumFATs*BPB_FATSz16;////因为dbr是逻辑第0扇区,所以其有2个扇区这么大,是操作系统的第一个扇区(逻辑上),所以根目录直接从fat上来
686: 80 91 ab 00 lds r24, 0x00AB
68a: 28 2f mov r18, r24
68c: 33 27 eor r19, r19
68e: 80 91 ac 00 lds r24, 0x00AC
692: 90 91 ad 00 lds r25, 0x00AD
696: 28 9f mul r18, r24
698: a0 01 movw r20, r0
69a: 29 9f mul r18, r25
69c: 50 0d add r21, r0
69e: 38 9f mul r19, r24
6a0: 50 0d add r21, r0
6a2: 11 24 eor r1, r1
6a4: 80 91 b2 02 lds r24, 0x02B2
6a8: 90 91 b3 02 lds r25, 0x02B3
6ac: 84 0f add r24, r20
6ae: 95 1f adc r25, r21
6b0: aa 27 eor r26, r26
6b2: bb 27 eor r27, r27
}
6b4: bc 01 movw r22, r24
6b6: cd 01 movw r24, r26
6b8: 08 95 ret
000006ba <GetDirSecCount>:
//-------------------------------------------------------------------------
uint16_t GetDirSecCount(void){ //目录项占用的扇区数
return BPB_RootEntCnt*32/BPB_BytesPerSec;//每个 目录项有 32个字节
6ba: 80 91 a5 00 lds r24, 0x00A5
6be: 90 91 a6 00 lds r25, 0x00A6
6c2: 20 91 ae 00 lds r18, 0x00AE
6c6: 30 91 af 00 lds r19, 0x00AF
6ca: 45 e0 ldi r20, 0x05 ; 5
6cc: 88 0f add r24, r24
6ce: 99 1f adc r25, r25
6d0: 4a 95 dec r20
6d2: e1 f7 brne .-8 ; 0x6cc <GetDirSecCount+0x12>
6d4: b9 01 movw r22, r18
6d6: 0e 94 f4 07 call 0xfe8 <__udivmodhi4>
6da: cb 01 movw r24, r22
6dc: 08 95 ret
000006de <DataStartSec>:
}
//-------------------------------------------------------------------------
uint32_t DataStartSec(void){ //获取数据区开始扇区号
6de: ef 92 push r14
6e0: ff 92 push r15
6e2: 0f 93 push r16
6e4: 1f 93 push r17
return DirStartSec()+GetDirSecCount();
6e6: 0e 94 43 03 call 0x686 <DirStartSec>
6ea: 7b 01 movw r14, r22
6ec: 8c 01 movw r16, r24
6ee: 0e 94 5d 03 call 0x6ba <GetDirSecCount>
6f2: aa 27 eor r26, r26
6f4: bb 27 eor r27, r27
6f6: 8e 0d add r24, r14
6f8: 9f 1d adc r25, r15
6fa: a0 1f adc r26, r16
6fc: b1 1f adc r27, r17
}
6fe: bc 01 movw r22, r24
700: cd 01 movw r24, r26
702: 1f 91 pop r17
704: 0f 91 pop r16
706: ff 90 pop r15
708: ef 90 pop r14
70a: 08 95 ret
0000070c <ClusConvLBA>:
//-------------------------------------------------------------------------
uint32_t ClusConvLBA(uint16_t ClusID){ //获取一个簇的开始扇区
70c: 0f 93 push r16
70e: 1f 93 push r17
710: 8c 01 movw r16, r24
return DataStartSec()+BPB_SecPerClus*(ClusID-2);
712: 0e 94 6f 03 call 0x6de <DataStartSec>
716: 9b 01 movw r18, r22
718: ac 01 movw r20, r24
71a: 80 91 a4 00 lds r24, 0x00A4
71e: 99 27 eor r25, r25
720: 02 50 subi r16, 0x02 ; 2
722: 10 40 sbci r17, 0x00 ; 0
724: 80 9f mul r24, r16
726: b0 01 movw r22, r0
728: 81 9f mul r24, r17
72a: 70 0d add r23, r0
72c: 90 9f mul r25, r16
72e: 70 0d add r23, r0
730: 11 24 eor r1, r1
732: cb 01 movw r24, r22
734: aa 27 eor r26, r26
736: bb 27 eor r27, r27
738: 82 0f add r24, r18
73a: 93 1f adc r25, r19
73c: a4 1f adc r26, r20
73e: b5 1f adc r27, r21
}
740: bc 01 movw r22, r24
742: cd 01 movw r24, r26
744: 1f 91 pop r17
746: 0f 91 pop r16
748: 08 95 ret
0000074a <ReadFAT>:
//-------------------------------------------------------------------------
uint16_t ReadFAT(uint16_t Index){ //读取文件分配表的指定项,index是fat表项
74a: 0f 93 push r16
74c: 1f 93 push r17
74e: 8c 01 movw r16, r24
uint16_t *RAM=(uint16_t*)BUFFER;
uint32_t SecID;
SecID=BPB_RsvdSecCnt+Index/256;///BPB_RsvdSecCnt 14 2 保留扇区数,每个扇区有256项,大于该项则跳到下一个扇区,index/256则可以取出块号,加上保留的区,一般为2,这里是读了bpb之后得到的
750: 29 2f mov r18, r25
752: 33 27 eor r19, r19
754: 80 91 b2 02 lds r24, 0x02B2
758: 90 91 b3 02 lds r25, 0x02B3
75c: 82 0f add r24, r18
75e: 93 1f adc r25, r19
760: aa 27 eor r26, r26
762: bb 27 eor r27, r27
ReadFatBlock(SecID);
764: bc 01 movw r22, r24
766: cd 01 movw r24, r26
768: 0e 94 9c 02 call 0x538 <ReadFatBlock>
return RAM[Index%256];//读出第index取余之后的那项
76c: 10 70 andi r17, 0x00 ; 0
76e: 00 0f add r16, r16
770: 11 1f adc r17, r17
772: 0e 54 subi r16, 0x4E ; 78
774: 1f 4f sbci r17, 0xFF ; 255
}
776: f8 01 movw r30, r16
778: 80 81 ld r24, Z
77a: 91 81 ldd r25, Z+1 ; 0x01
77c: 1f 91 pop r17
77e: 0f 91 pop r16
780: 08 95 ret
00000782 <WriteFAT>:
//-------------------------------------------------------------------------
void WriteFAT(uint16_t Index,uint16_t Value){ //写文件分配表的指定项,把16位,2B的簇号写入,每个fat表项为2B大小
782: af 92 push r10
784: bf 92 push r11
786: cf 92 push r12
788: df 92 push r13
78a: ef 92 push r14
78c: ff 92 push r15
78e: 0f 93 push r16
790: 1f 93 push r17
792: 8c 01 movw r16, r24
794: 5b 01 movw r10, r22
uint16_t *RAM=(uint16_t*)BUFFER;
uint32_t SecID;
SecID=BPB_RsvdSecCnt+Index/256;
796: 29 2f mov r18, r25
798: 33 27 eor r19, r19
79a: 80 91 b2 02 lds r24, 0x02B2
79e: 90 91 b3 02 lds r25, 0x02B3
7a2: 82 0f add r24, r18
7a4: 93 1f adc r25, r19
7a6: 6c 01 movw r12, r24
7a8: ee 24 eor r14, r14
7aa: ff 24 eor r15, r15
ReadFatBlock(SecID);
7ac: c7 01 movw r24, r14
7ae: b6 01 movw r22, r12
7b0: 0e 94 9c 02 call 0x538 <ReadFatBlock>
RAM[Index%256]=Value;
7b4: 10 70 andi r17, 0x00 ; 0
7b6: 00 0f add r16, r16
7b8: 11 1f adc r17, r17
7ba: 0e 54 subi r16, 0x4E ; 78
7bc: 1f 4f sbci r17, 0xFF ; 255
7be: f8 01 movw r30, r16
7c0: b1 82 std Z+1, r11 ; 0x01
7c2: a0 82 st Z, r10
WriteFatBlock(SecID);
7c4: c7 01 movw r24, r14
7c6: b6 01 movw r22, r12
7c8: 0e 94 aa 02 call 0x554 <WriteFatBlock>
7cc: 1f 91 pop r17
7ce: 0f 91 pop r16
7d0: ff 90 pop r15
7d2: ef 90 pop r14
7d4: df 90 pop r13
7d6: cf 90 pop r12
7d8: bf 90 pop r11
7da: af 90 pop r10
7dc: 08 95 ret
000007de <GetEmptyDIR>:
}
//-------------------------------------------------------------------------
uint16_t GetEmptyDIR(void){ //获取根目录中可以使用的一项
7de: cf 92 push r12
7e0: df 92 push r13
7e2: ef 92 push r14
7e4: ff 92 push r15
7e6: 0f 93 push r16
7e8: 1f 93 push r17
7ea: cf 93 push r28
7ec: df 93 push r29
uint16_t i,DirSecCut,DirStart,m,ID=0;
7ee: 00 e0 ldi r16, 0x00 ; 0
7f0: 10 e0 ldi r17, 0x00 ; 0
DirSecCut=GetDirSecCount();////目录项占用的扇区数
7f2: 0e 94 5d 03 call 0x6ba <GetDirSecCount>
7f6: 6c 01 movw r12, r24
DirStart=DirStartSec();
7f8: 0e 94 43 03 call 0x686 <DirStartSec>
for(i=0;i<DirSecCut;i++){
7fc: 78 01 movw r14, r16
7fe: 0c 15 cp r16, r12
800: 1d 05 cpc r17, r13
802: f0 f4 brcc .+60 ; 0x840 <GetEmptyDIR+0x62>
804: eb 01 movw r28, r22
ReadFatBlock(DirStart+i);//读出一个扇区来,16*32=512,每个文件有32个字节的属性,也就是说最多放16*32(共有32个扇区)个文件
806: ce 01 movw r24, r28
808: aa 27 eor r26, r26
80a: bb 27 eor r27, r27
80c: bc 01 movw r22, r24
80e: cd 01 movw r24, r26
810: 0e 94 9c 02 call 0x538 <ReadFatBlock>
814: e2 eb ldi r30, 0xB2 ; 178
816: f0 e0 ldi r31, 0x00 ; 0
for(m=0;m<16;m++){//一个一个文件找过去
if(BUFFER[m*32]==0)return ID;//监察表的第一项,也就是偏移量为0的项,如果为00h, 表示目录项为空
818: 80 81 ld r24, Z
81a: b0 96 adiw r30, 0x20 ; 32
81c: 88 23 and r24, r24
81e: 81 f0 breq .+32 ; 0x840 <GetEmptyDIR+0x62>
if(BUFFER[m*32]==0xe5)return ID;//若为E5H, 表明目录项曾被使用, 但对应的文件或文件夹已被删除
820: 85 3e cpi r24, 0xE5 ; 229
822: 71 f0 breq .+28 ; 0x840 <GetEmptyDIR+0x62>
ID++;
824: 0f 5f subi r16, 0xFF ; 255
826: 1f 4f sbci r17, 0xFF ; 255
828: 82 e0 ldi r24, 0x02 ; 2
82a: e2 39 cpi r30, 0x92 ; 146
82c: f8 07 cpc r31, r24
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -