📄 bootlace.inc
字号:
movl ABS(total_sectors), %eax subl $4, %edi stosl2: /* drive number, byte, etc... */ addl $(1+1+1+4+11+8), %esi addl $(1+1+1+4+11+8), %edi //movl $0xFFB6FCFA, %eax /* CLI, CLD, MOV DH,FF */ lodsw stosw lodsb stosb lodsb //decl %edi /* partition number, byte */ movb ABS(floppy), %al stosb /* Machine code begins at offset 0x42, 444 bytes without * the ending 2 bytes of boot signature */ //movl $ABS(_start1 + 0x642), %esi movl $(444 / 4), %ecx repz movsl movl $1, ABS(sectors_to_write) movl $ABS(msg_fstype_fat16_allow), %ecx call 8f /* linux_print */ clc popal ret1: movl $0, ABS(sectors_to_write) movl $ABS(msg_unsupported_fstype), %ecx call 8f /* linux_print */ stc popal ret//----------------------------------------------------------------------------//print decimal number in EAX6: /* print EAX value in decimal format */ pushal#if 0 cld movl $ABS(number_digits), %edi xchgl %eax, %edx // save EAX to EDX movw $0x2020, %ax // two spaces stosw stosw stosw stosw stosw decl %edi // EDI points to the last digit xchgl %eax, %edx // restore EAX from EDX#endif std movl $ABS(number_digits + 9), %edi movl $10, %ebp1: xorl %edx, %edx divl %ebp // quo=EAX, rem=EDX xchgl %eax, %edx orb $0x30, %al stosb xchgl %eax, %edx testl %eax, %eax jnz 1b /* all digits are stored */ incl %edi // points to the digit string movl %edi, %ecx call 8f /* linux_print */ cld popal ret//----------------------------------------------------------------------------//parse_number:7: /* input: EDI points to the number * EBX upper limit of the number * output: EBX the value of the number * EDX changed * ESI changed * EBP changed * CF=1 failure * CF=0 success */ pushl %eax pushl %ebx /* upper limit */ cld movl %edi, %esi movl $0xffffffff, %edx xorl %ebx, %ebx lodsw cmpw $0x5830, %ax /* 0X */ je 1f cmpw $0x7830, %ax /* 0x */ je 1f /* decimal */ decl %esi decl %esi movl $10, %ebp2: xorl %eax, %eax lodsb cmpb $0, %al je 4f /* CF=0 */ cmpb $0x30, %al jb 3f cmpb $0x39, %al ja 3f subb $0x30, %al pushl %eax movl %ebx, %eax mull %ebp movl %eax, %ebx popl %eax jc 3f addl %eax, %ebx jc 3f popl %eax pushl %eax /* upper limit */ cmpl %eax, %ebx ja 3f jmp 2b1: /* hex */ movl $16, %ebp2: xorl %eax, %eax lodsb cmpb $0, %al je 4f /* CF=0 */ cmpb $0x30, %al jb 3f cmpb $0x39, %al jbe 1f orb $0x20, %al cmpb $0x61, %al jb 3f cmpb $0x66, %al ja 3f subb $0x27, %al1: subb $0x30, %al pushl %eax movl %ebx, %eax mull %ebp movl %eax, %ebx popl %eax jc 3f addl %eax, %ebx jc 3f popl %eax pushl %eax /* upper limit */ cmpl %eax, %ebx ja 3f jmp 2b3: stc popl %eax /* upper limit */ popl %eax ret4: testl %edx, %edx /* CF=0 */ jnz 3b popl %eax /* upper limit */ popl %eax ret//----------------------------------------------------------------------------//linux_print:8: /* print a message. * input: ECX points to message string * output: message is displayed on the stdout device */ /* ssize_t write(int fd, const void *buf, size_t count) */ pushal#ifdef __DOS_16 cld movl %ecx, %esi// movw %si, %dx// movb $0x09, %ah // WRITE STRING TO STANDARD OUTPUT// int $0x21 // call DOS// ret1: lodsb (%si), %al // get token cmpb $0, %al // end of string? je 1f#if 0 /* use BIOS independent of DOS */ xorw %bx, %bx // video page 0 movb $0x0e, %ah // print it int $0x10 // via TTY mode#else /* use stdout for redirection of the output */ movb %al, %dl // character to write movb $0x02, %ah // WRITE CHARACTER TO STANDARD OUTPUT int $0x21 // call DOS#endif jmp 1b // until done1:#else pushl %ecx movl %ecx, %edi # scan the message string ... movl $(msg_end - msg_start), %ecx movb $0, %al # ... find the ending zero byte cld repnz scasb movl %edi, %edx popl %ecx # ECX points to the message subl %ecx, %edx # EDX=message length decl %edx # discard the ending zero byte movl $4, %eax # sys_write movl $1, %ebx # file descriptor = stdout int $0x80#endif popal ret//----------------------------------------------------------------------------//probe_geometry:9: pushal addl $0x200, %esi movw $0, ABS(Cmax) movl $0, ABS(Hmax) movw $0, ABS(Smax) movl $0, ABS(i) # partition number1: cmpl $4, ABS(i) jae 1f /* the boot indicator must be 0x80(bootable) or 0(non-bootable) */ movl ABS(i), %ebx movl ABS(i), %edi shll $4, %ebx # EBX = i * 16 movb -66(iBX, iSI), %al # boot_indicator shlb $1, %al jnz 6f /* geometry_probe_failed */ /* check if the entry is empty, i.e., all the 16 bytes are 0 */ movl -66(iBX, iSI), %eax orl -62(iBX, iSI), %eax orl -58(iBX, iSI), %eax orl -54(iBX, iSI), %eax jz 2f # empty partition entry /* valid partitions never start at 0, because this is where the MBR * lives; and more, the number of total sectors should be non-zero. */ cmpl $0, -58(iBX, iSI) # start_lba jz 6f /* geometry_probe_failed */ cmpl $0, -54(iBX, iSI) # total_sectors jz 6f /* geometry_probe_failed */ /* the partitions should not overlap each other */ movl $-1, ABS(j) // j = -13: // for (j = 0; j < i; j++) incl ABS(j) // j++ cmpl %edi, ABS(j) # i = EDI jae 3f // j >= i, break. movl -58(iBX, iSI), %ecx # ECX=P[i].start_lba movl ABS(j), %edx shll $4, %edx # EDX = j * 16 MOVL -58(%edx, %esi), %eax # EAX=P[j].start_lba // if ((P[j].start_lba <= P[i].start_lba) && (P[j].start_lba + P[j].total_sectors >= P[i].start_lba + P[i].total_sectors)) cmpl %ecx, %eax ja 4f pushl %ecx pushl %eax addl -54(iBX, iSI), %ecx // ECX = P[i].start_lba + P[i].total_sectors ADDL -54(%edx, %esi), %eax // EAX = P[j].start_lba + P[j].total_sectors cmpl %ecx, %eax popl %eax popl %ecx jb 4f jmp 3b //continue4: // if ((P[j].start_lba >= P[i].start_lba) && (P[j].start_lba + P[j].total_sectors <= P[i].start_lba + P[i].total_sectors)) cmpl %ecx, %eax jb 4f pushl %ecx pushl %eax addl -54(iBX, iSI), %ecx // ECX = P[i].start_lba + P[i].total_sectors ADDL -54(%edx, %esi), %eax // EAX = P[j].start_lba + P[j].total_sectors cmpl %ecx, %eax popl %eax popl %ecx ja 4f jmp 3b //continue4: cmpl %ecx, %eax jae 4f // P[j].start_lba < P[i].start_lba subl %eax, %ecx // ECX = P[i].start_lba - P[j].start_lba CMPL -54(%edx, %esi), %ecx # ECX < P[j].total_sectors jmp 5f4: // P[j].start_lba >= P[i].start_lba subl %ecx, %eax // EAX = P[j].start_lba - P[i].start_lba cmpl -54(iBX, iSI), %eax # EAX < P[i].total_sectors5: jb 6f /* geometry_probe_failed */ jmp 3b //continue3: /* the start cylinder number */ movzwl -64(iBX, iSI), %eax # start_sector_cylinder movl %eax, %edx andw $0x003f, %dx jz 6f /* geometry_probe_failed */ movw %dx, ABS(X) # the sector number cmpw %dx, ABS(Smax) jae 3f movw %dx, ABS(Smax)3: movl -58(iBX, iSI), %ecx # start_lba incl %ecx subl %edx, %ecx movl $ABS(L), %edx MOVL %ecx, (%edx, %edi, 8) # L[i] ///* partitions should not start at the first track, the MBR-track */ //movw ABS(Smax), %dx //cmpw %dx, -58(%ebx, %esi) # start_lba //jb 6f /* geometry_probe_failed */ shrb $6, %al xchgb %al, %ah movl $ABS(C), %edx MOVW %ax, (%edx, %edi, 4) # C[i] cmpw %ax, ABS(Cmax) jae 3f movw %ax, ABS(Cmax)3: //movl ABS(i), %ebx //shll $4, %ebx # EBX = ABS(i) * 16 movzbl -65(iBX, iSI), %eax # start_head movl $ABS(H), %edx MOVL %eax, (%edx, %edi, 4) # H[i] cmpl %eax, ABS(Hmax) jae 3f movl %eax, ABS(Hmax)3: /* the end cylinder number */ movzwl -60(iBX, iSI), %eax # end_sector_cylinder movl %eax, %edx andw $0x003f, %dx jz 6f /* geometry_probe_failed */ movw %dx, ABS(Y) # the sector number cmpw %dx, ABS(Smax) jae 3f movw %dx, ABS(Smax)3: movl -58(iBX, iSI), %ecx # start_lba addl -54(iBX, iSI), %ecx # total_sectors # XXX: possible overflow! subl %edx, %ecx jb 6f /* geometry_probe_failed */ addl $4, %edi # EDI=i+4 movl $ABS(L), %edx MOVL %ecx, (%edx, %edi, 8) # L[i+4] movl %ecx, %ebp # save ECX to EBP /* partitions should not start at the first track, the MBR-track */ movw ABS(Smax), %dx cmpw %dx, -58(iBX, iSI) # start_lba jb 6f /* geometry_probe_failed */ shrb $6, %al xchgb %al, %ah movl $ABS(C), %edx MOVW %ax, (%edx, %edi, 4) # C[i+4] cmpw %ax, ABS(Cmax) jae 3f movw %ax, ABS(Cmax)3: xchgl %eax, %ecx # save AX to CX //movl ABS(i), %ebx //shll $4, %ebx # EBX = ABS(i) * 16 movzbl -61(iBX, iSI), %eax # end_head movl $ABS(H), %edx MOVL %eax, (%edx, %edi, 4) # H[i+4] cmpl %eax, ABS(Hmax) jae 3f movl %eax, ABS(Hmax)3: /* Check the large disk partition -- Win98 */ cmpw $63, ABS(Y) jne 3f cmpl %eax, ABS(Hmax) # EAX=H[i+4] jne 3f cmpw %cx, ABS(Cmax) # ECX=C[i+4] jne 3f cmpl $254, %eax # EAX=ABS(Hmax) jnb 4f cmpw $1022, %cx # CX=ABS(Cmax) jb 3f4: movl $63, %edx # EDX=ABS(Y) addl %edx, %ebp incl %eax mull %edx # EDX:EAX=product # EDX=0 # EAX high word = 0 # AX=(Hmax+1)*63 pushl %eax # EAX=(Hmax+1)*63 incl %ecx mull %ecx # EDX:EAX=product # EDX=0 cmpl %ebp, %eax popl %eax # EAX=(Hmax+1)*63 jnb 3f /* EDI=i+4 at this moment */ pushl %eax # EAX=(Hmax+1)*63 subl $4, %edi # EDI=i movl $ABS(C), %ebx MOVZWL (%ebx, %edi, 4), %eax # C[i] movl ABS(Hmax), %ebp # Hmax incl %ebp pushl %eax # EAX=C[i] movl $ABS(H), %ebx MOVL (%ebx, %edi, 4), %ecx # H[i] mull %ebp # EDX=0, EAX=product addl %ecx, %eax movl $63, %edx mull %edx # EDX=0, EAX=product movl $ABS(L), %ebx MOVL (%ebx, %edi, 8), %ebp # L[i] cmpl %ebp, %eax popl %eax # EAX=C[i] jae 4f /* calculate CHS numbers from start LBA */ //pushl %eax # EAX=C[i] xorl %edx, %edx xchgl %eax, %ebp # EBP=C[i], EDX:EAX=L[i] divl ABS(Y) # Y=63 # quo=EAX, rem=EDX incl %edx # sector number cmpw %dx, ABS(X) je 15f cmpw $63, ABS(X) jne 4f15: xorl %edx, %edx movl ABS(Hmax), %ebx incl %ebx # EBX=Hmax+1 divl %ebx # quo=EAX=cylinder number # rem=EDX=head number cmpl %edx, %ecx # ECX=H[i] je 15f decl %ebx # EBX=Hmax cmpl %ebx, %ecx jne 4f15: /* EAX=calculated cylinder number, EBP=C[i] */ cmpl ABS(Cmax), %ebp je 4f andw $0x3ff, %ax # low 10 bit of calculated cylinder cmpw %ax, %bp//5:// cmpw ABS(Cmax), %ax// jne 4f// cmpl ABS(Hmax), %ecx// jne 4f// cmpw $63, ABS(X)4: popl %eax jne 6f /* geometry_probe_failed */ jmp 5f3: /* Check the large disk partition -- Win2K */ /* EDI=i+4 at this moment */ cmpw $63, ABS(Y) jne 3f movl $ABS(H), %edx MOVL (%edx, %edi, 4), %eax # H[i+4] cmpl %eax, ABS(Hmax) # EAX=H[i+4] jne 3f movl $ABS(L), %edx MOVL (%edx, %edi, 8), %ebp # L[i+4] movl $ABS(C), %edx MOVZWL (%edx, %edi, 4), %ecx # C[i+4] incl %ecx incl %eax mull %ecx # EDX=0, EAX=product mull ABS(Y) # Y=63, EDX=0, EAX=product addl ABS(Y), %ebp cmpl %ebp, %eax jnb 3f movl ABS(Hmax), %eax incl %eax mull ABS(Y) # Y=63, EDX=0, EAX=product xorl %edx, %edx xchgl %eax, %ebp # EBP=(Hmax+1)*63 # EAX=L[i+4]+Y divl %ebp # EAX=quo, EDX=rem testl %edx, %edx jnz 3f decl %eax andl $0x3ff, %eax decl %ecx cmpl %eax, %ecx jne 3f /* EDI=i+4 at this moment */ subl $4, %edi # EDI=i movl $ABS(C), %ebx MOVL (%ebx, %edi, 4), %eax # C[i] pushl %eax mull %ebp # EBP=(Hmax+1)*63 # EDX=0, EAX=product pushl %ebp # EBP=(Hmax+1)*63 xchgl %eax, %ebp # EBP=product movl $ABS(H), %ebx MOVL (%ebx, %edi, 4), %eax # H[i] mull ABS(Y) # Y=63, EDX=0, EAX=H[i]*63 pushl %eax addl %eax, %ebp movl $ABS(L), %ebx MOVL (%ebx, %edi, 8), %eax # L[i] cmpl %eax, %ebp popl %ebx # EBX=H[i]*63 popl %ebp # EBP=(Hmax+1)*63 popl %ecx # ECX=C[i] xchgl %eax, %ebp ja 6f /* geometry_probe_failed */ je 5f xchgl %eax, %ebp subl %ebx, %eax xorl %edx, %edx divl %ebp # EAX=quo, EDX=rem testl %edx, %edx jnz 6f /* geometry_probe_failed */ andl $0x3ff, %eax cmpl %eax, %ecx jne 6f /* geometry_probe_failed */ xchgl %eax, %ebp jmp 5f3: /* Maximum of C[n] * (H * S) + H[n] * S = 1023 * 255 * 63 + 254 * 63 = 0xFB03C1 */ /* EDI=i+4 at this moment */ movl $ABS(L), %edx MOVL (%edx, %edi, 8), %ebp # L[i+4] cmpl $0xFB03C1, %ebp jbe 3f /* set H/S to max */ cmpl $254, ABS(Hmax) jae 4f movl $254, ABS(Hmax)4: movw $63, ABS(Smax) xorl %edx, %edx movl %ebp, %eax divl ABS(Smax) testl %edx, %edx jnz 6f /* geometry_prob
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -