汇编引导区和测试

来源:互联网 发布:js控制input disabled 编辑:程序博客网 时间:2024/06/05 17:32
LBA_ADDRequ 250section bootload align=16 vstart=0x7c00start:mov ax, 0mov ss, axmov sp, axmov ax, [cs:phy_addr]mov dx, [cs:phy_addr + 2]mov bx, 16div bxmov ds, axmov es, axpush 0xe0push 0push 0push LBA_ADDR push 0x01xor bx, bxcall _readHd;jmp   showTest   ;本句话可以测试是否先从硬盘的250扇区开始的用户读到内存地址0x10000;接下来准备设置地址0x10000后面用户程序的各种段的地址;用户程序长度mov bx, 0mov ax, [ds:bx]mov dx, [ds:bx+2];填充开始执行的地址即0x04的两个字节;计算原来的地址;code段地址;mov ax, 4098;mov [ds:0x06], ax;mov ax, 4098;mov [ds:0x0c], ax;mov ax, 4101;mov [ds:0x10], ax;jmp far [0x04];计算入口点代码段基址 direct:mov dx,[0x08]mov ax,[0x06]call _calc_segment_basemov [0x06],ax                   ;回填修正后的入口点代码段基址 ;开始处理段重定位表mov cx,[0x0a]                   ;需要重定位的项目数量mov bx,0x0c                     ;重定位表首地址realloc:mov dx,[bx+0x02]                ;32位地址的高16位 mov ax,[bx]call _calc_segment_basemov [bx],ax                     ;回填段的基址add bx,4                        ;下一个重定位项(每项占4个字节) loop realloc ;jmp far [0x04];;;;;;;;;;;;;;;;;;;;;;;;;;;;用于测试,测试加载到内存0x10000开始后用户程序地址mov ax, 0xb800mov es, axmov ax,[cs:number]                ;计算各个数位        mov bx,ax        mov cx,5                      ;循环次数         mov si,10                     ;除数 mov ax, [ds:0x12]digit: xor dx,dxdiv simov [bx],dl                   ;保存数位inc bx loop digit;显示各个数位mov bx,[cs:number]mov si,4         xor di, dishow:mov al,[bx+si]add al,0x30mov ah,0x04mov [es:di],axadd di,2dec sijns showmov word [es:di],0x0744jmp near $;-------------------------------------------------------------------------------_calc_segment_base:                 ;计算16位段地址 ;输入:DX:AX=32位物理地址 ;返回:AX=16位段基地址 push dx                          add ax,[cs:phy_addr]adc dx,[cs:phy_addr + 0x02]shr ax,4ror dx,4and dx,0xf000or ax,dxpop dxret;@showTest:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mov cx, 512;xor si, si;xor di, di;mov ax, 0xb800;mov es, ax;@showStr:;mov al, [ds:si];mov [es:di], al;inc si;inc di;mov byte [es:di], 0x07;inc di;loop @showStr;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;_readHd:push bpmov bp, spmov dx, 0x1f2mov al, [bp+4]out dx, almov dx, 0x1f3mov al, [bp+6]out dx, almov dx, 0x1f4mov al, [bp+8]out dx, almov dx, 0x1f5mov al, [bp+10]out dx, almov dx, 0x1f6mov al, [bp+12]out dx, almov dx, 0x1f7mov al, 0x20out dx, al@wait:in al, dxand al, 0x88cmp al, 0x08jnz @waitmov cx, 512mov dx, 0x1f0@readHd:in al, dxmov [bx], alinc bxloop @readHdpop bpretphy_addr dd 0x10000number db 0,0,0,0,0,0,0times 510 - ($ - $$) db 0dw 0xaa55section header align=16 vstart=0prog_length dd prog_end ;0x00code_entrydw start;0x04dd section.code.start;0x06table_size  dw (header_end - codeSegAddr)/4;0x0acodeSegAddr dd section.code.start;0x0cdataSegAddr dd section.data.start;0x10header_end:;用户程序section code align=16 vstart=0start:mov ax, [dataSegAddr]mov ds, axmov ax, 0xb800mov es, axmov si, 0mov di, 0mov bx, szInformov cx, data_end - szInfor@ShowStr:mov al, [ds:si+bx]mov [es:di], alinc siinc dimov byte [es:di], 0x07inc diloop @ShowStr@Hlt:hlt jmp @Hltsection data align=16 vstart=0szInfor db "Now we are in user space Fuck!"data_end:section trail align=16prog_end:

0 0