1

i want to compile a boot sector code from bootloader.asm to bootloader.bin using masm. But it is throwing error "must be in segment block". can't we use segmentation in boot loader code if not then what is the solution for the error "must be in segment block".

I am using following command to compile boot loader code:

MASM myboot.asm

after which i can use LINK to generate bin file.

My boot sector code is as given below:

                   JMP     START
                   NOP                                        

bsOEM_NAME            DB      'MSDOS5.0'      ;  8 bytes
bsBYTES_PER_SECTOR    DW      ?
bsSECTORS_PER_CLUSTER DB      ?
bsRESERVED_SECTORS    DW      ?
bsFAT_COPIES          DB      ?
bsROOT_DIR_ENTRIES    DW      ?
bsTOTAL_DISK_SECTORS  DW      ?
bsMEDIA_DESCRIPTOR    DB      ?
bsSECTORS_PER_FAT     DW      ?
bsSECTORS_PER_TRACK   DW      ?
bsSIDES               DW      ?
bsHIDDEN_SECTORS_HIGH DW      ?
bsHIDDEN_SECTORS_LOW  DW      ?
bsTOTAL_NUM_SECTORS   DD      ?
bsPHYS_DRIVE_NUMBER_1 DB      ?
bsPHYS_DRIVE_NUMBER_2 DB      ?
bsBOOT_RECORD_SIG     DB      29h
bsVOL_SERIAL_NUM      DD      1F61A800h
bsVOLUME_LABEL        DB      'NO NAME    '   ; 11 bytes
bsFILE_SYSTEM_ID      DB      'FAT16   '      ;  8 bytes

;Disk Parameter Block

;   The DPB is located in the ROM BIOS at the address pointed to 
;by 0078h.
;   The 11 bytes starting from START are overwritten at COPY_DPB 
;with the
;   DPB (7C3E-7C48).  This is what the area looks like *after* 
;the copy
;   at COPY_DPB:
; 

START               CLI                  ; Disable interrupts
                XOR        AX,AX     ; AX=0000
                MOV        SS,AX     ; SS=0000
                MOV        SP,7C00   ; SP grows in decrements
                PUSH       SS                                 
                POP        ES        ; ES=0000
                MOV        BX,0078   ; The address of the ROM
                                     ; BIOS disk table is 78h.
                                     ; (INT 18h).  ROM routine
                                    ; copies this address during
                                     ; cold boot initialization.
                                                           
                LDS        SI,[BX]  ; SI points to ROMBIOS table
                                    ; The source for the copy
                PUSH       DS                                 
                PUSH       SI                                 
                PUSH       SS                                 
                PUSH       BX                                 
                MOV        DI,START  ; Address of destination
                MOV        CX,000B   ; Size of area to copy
                                          ; (Disk parameters)
                CLD                  ; Set direction flag to inc
                REPZ                 ; Move 11 bytes from the
                                     ; disk parameter area to
                                     ; overlap with the start
                                          ; of the code at 7D3E
                                          ; (save space?)
                MOVSB                                         

                PUSH       ES                                 
                POP        DS        ; DS=0000
                MOV        BYTE PTR [DI-02],0F
                                     ; At this point, DI points
                                     ; to 7C49, one byte after
                                     ; the last thing copied.
                                     ; Destination operand is
                                     ; dpbHEAD_SETTLE_TIME.
                MOV        CX,bsSECTORS_PER_TRACK
                MOV        [DI-07],CL ; Destination operand is
                                      ; dpbSECTORS_PER_TRACK.
                MOV        [BX+02],AX ; Destination operand is
                                           ; dpbMOTOR_OFF_DELAY.
                MOV        WORD PTR [BX],START
                STI                  ; The code at 7C6B installs
                                     ; the new Int 1E into the
                                     ; interrupt table at
                                     ; 0000:0078. At 7C68, AX is
                                     ; 0. START is the offset
                                     ; for the new INT 1E.
                INT        13        ; Reset drives (AX=0000)
                JB         ERROR_IN_BOOT_1
                XOR        AX,AX                              
                CMP        bsTOTAL_DISK_SECTORS,AX
                JZ         LOOP_1

                MOV        CX,bsTOTAL_DISK_SECTORS
                MOV        bsTOTAL_NUM_SECTORS,CX
LOOP_1          MOV        AL,bsFAT_COPIES       
                MUL        WORD PTR bsSECTORS_PER_FAT
                ADD        AX,bsHIDDEN_SECTORS_HIGH
                ADC        DX,bsHIDDEN_SECTORS_LOW
                ADD        AX,bsRESERVED_SECTORS
                ADC        DX,+00                             
                MOV        [7C50],AX                          
                MOV        [7C52],DX                          
                MOV        [7C49],AX                          
                MOV        [7C4B],DX                          
                MOV        AX,0020                            
                MUL        WORD PTR bsROOT_DIR_ENTRIES
                MOV        BX,bsBYTES_PER_SECTOR
                ADD        AX,BX                              
                DEC        AX                                 
                DIV        BX                                 
                ADD        [7C49],AX                          
                ADC        WORD PTR [7C4B],+00                
                MOV        BX,0500   ; Buffer for root directory
                MOV        DX,[7C4B]                          
                MOV        AX,[7C49]                          
                CALL       CALCULATE

                JB         ERROR_IN_BOOT_1                    
                MOV        AL,01                              
                CALL       READ_SECTOR
                JB         ERROR_IN_BOOT_1 ;Error? Print message
                                            ; and reboot.
                MOV        DI,BX
                MOV        SI,OFFSET FILE_IO_SYS
                REPZ
                CMPSB
                JNZ        ERROR_IN_BOOT_1 ;First file in root
                                           ; dir is not IO.SYS?
                                                ; Print error.
                LEA        DI,[BX+20]                         
                MOV        CX,000B      ; 11 characters in DOS
                                             ; filename.
                REPZ                                          
                CMPSB                 ; Is second file in root
                                           ; MSDOS.SYS?
                JZ         LOOP_2     ; Yes?  Then continue on.
ERROR_IN_BOOT_1     MOV        SI,OFFSET NON_SYSTEM_DISK
                CALL       WRITE_STRING
                XOR        AX,AX       
                INT        16          
                POP        SI          
                POP        DS          
                POP        [SI]        
                POP        [SI+02]                            
                INT        19                                 

ERROR_IN_BOOT_2 POP        AX                                 
                POP        AX                                 
                POP        AX                                 
                JMP        ERROR_IN_BOOT_1
LOOP_2          MOV        AX,[BX+1A]                         
                DEC        AX                                 
                DEC        AX                                 
                MOV        BL,SECTORS_PER_CLUSTER
                XOR        BH,BH                              
                MUL        BX                                 
                ADD        AX,[7C49]                          
                ADC        DX,[7C4B]                          
                MOV        BX,0700      ; DOS loading buffer
                MOV        CX,0003                            
LOOP_3          PUSH       AX                                 
                PUSH       DX                                 
                PUSH       CX                                 
                CALL       CALCULATE      
                JB         ERROR_IN_BOOT_2
                MOV        AL,01          
                CALL       READ_SECTOR    
                POP        CX             
                POP        DX             
                POP        AX                                 
                JB         ERROR_IN_BOOT_1
                ADD        AX,0001                            
                ADC        DX,+00                             
                ADD        BX,BYTES_PER_SEC
                LOOP       LOOP_3                               
                MOV        CH,MEDIA_DESCRIPTOR
                MOV        DL,PHYS_DRIVE_NUMBER_1
                MOV        BX,[7C49]                          
                MOV        AX,[7C4B]                          
                JMP        0070:0000    ; Transfer to ROM BIOS

 WRITE_STRING   LODSB                                         
                OR         AL,AL                              
                JZ         RETURN_FROM_2
                MOV        AH,0E       
                MOV        BX,0007     
                INT        10          
                JMP        WRITE_STRING

CALCULATE       CMP        DX,SECTORS_PER_TRACK
                JNB        RETURN_FROM_1
                DIV        WORD PTR SECTORS_PER_TRACK
                INC        DL                                 
                MOV        [7C4F],DL                          
                XOR        DX,DX                              
                DIV        WORD PTR SIDES
                MOV        PHYS_DRIVE_NUMBER_2,DL
                MOV        [7C4D],AX                          
                CLC                                           
                RET                                           

RETURN_FROM_1       STC                                           
RETURN_FROM_2       RET                                           

READ_SECTOR         MOV        AH,02      ; 02h is ReadSector .
                MOV        DX,[7C4D]  ; DH is head/side number.
                                        ; DL is drive number.
                                      ; (Bit 7 of DL set for HD)
                MOV        CL,06      ; CL is sector number.
                SHL        DH,CL      ; Multiply DH (number of
                                           ; heads) by 6.
                OR         DH,[7C4F]
                MOV        CX,DX
                XCHG       CH,CL
                MOV        DL,bsPHYS_DRIVE_NUMBER_1
                MOV        DH,bsPHYS_DRIVE_NUMBER_2
                INT        13           ; ReadSector
                RET

NON_SYSTEM_DISK     DB      13,10
                DB      'Non-System disk or disk error'
                DB      13,10
                DB      'Replace and press any key when ready'
                DB      13,10,0
FILE_IO_SYS         DB      'IO      SYS'
FILE_MSDOS_SYS      DB      'MSDOS   SYS'
                DB      0,0,55,AA
iammca
  • 21
  • 3
  • 1
    If you are using MASM 6.15 or higher I'd use `.model tiny` `.code` at the top and `end` at the bottom of the file. Everything into the simplified code section called `.code`. But that wont solve all your problems. One big one is that it seems like this code was intended to be used by debug.exe/debug.com or some very antiquated assembler given that you don't use a `h` prefix to denote hexadecimal numbers. Every hex number in your code is being treated as decimal by MASM and it will throw errors on most of them. – Michael Petch Sep 24 '20 at 09:53
  • Michael you are right, compiler is generating errors on every occurrences of [memory address] (e.g. MOV [7C50], AX) by mentioning "nondigit in number",AS "C" is not a digit in "7C50", but when i add "h" for example (MOV [7C50h],AX), then it is throwing another error by mentioning "immediate operand not allowed", As obviously [7C50h] is an immediate operand. what is the solution please explain. – iammca Sep 24 '20 at 12:08
  • Because you aren't using labels to data items you will need to override with DS using something like `MOV ds:[7C50h], AX`. This is a peculiarity with MASM and compatible assemblers. – Michael Petch Sep 24 '20 at 12:18
  • thanks Michael your answer help me alot but still my code is producing an error by mentioning "segment, group, or segment register expected" at line "JMP 0070:0000h" ; Transfer to ROM BIOS – iammca Sep 25 '20 at 02:15
  • MASM doesn't support encoding FAR JMP directly like that. You could try replacing the JMP with: `db 0eah` `dw 0000h, 0070h` – Michael Petch Sep 25 '20 at 02:20
  • thanks Michael, i still have confusion, you means that we will declare two variables one is for "db 0eah" and another one for "dw 0000h,0070h". is it so. then what should i do to access memory location 0070:0000h. please explain in little more detail that how should i code this. – iammca Sep 25 '20 at 02:38
  • i will be thankful if you write code lines to achieve this functionality. – iammca Sep 25 '20 at 02:41
  • Replace `JMP 0070h:0000h` with 2 lines. `db 0eah` followed by `dw 0000h, 0070h` , This manually encodes a FAR JMP. byte 0eah is the instruction opcode for a FAR JMP. The word after that is the offset portion of the jmp instruction and the word after that is the segment. – Michael Petch Sep 25 '20 at 02:41
  • Other way of doing it that are more involved can be found here: https://stackoverflow.com/a/32707007/3857942 – Michael Petch Sep 25 '20 at 02:42
  • I have the bootloader code given above. How can I run this to get ms dos run. That is i can found drive letter A:\> – iammca Oct 08 '20 at 16:56

0 Answers0