460 Assignment #1
REQUIREMENTS
##########################################################################
(DUE in ONE WEEK)
Turn in a floppy disk and a hard copy. Sign up for DEMO in Sloan 327.
##########################################################################
The following assembly file may be used as part of a boot program.
As shown, the assembly code calls _main, which can be written in C.
In YOUR main() : call setVideo() to clear the screen.
while(1){
call myprints() to print a string, e.g. What's you name?
call mygets() to read (and echo each char) user's NAME.
display a message such as Welcome! NAME
if NAME equals "quit" : return;
}
YOU MUST implement the functions
myprints(s) char *s;
mygets(s) char *s;
in C, which call putc(), getc() in assembly.
With YOUR myc.c file, generate a bootable diskette as follows:
Under Linux (as a sh script file)
#===================================================
bcc -c myc.c
as86 -o mys.o mys.s
ld86 -d mys.o myc.o /usr/lib/bcc/libc.a
# check a.out size, NUST be <= 1024 bytes
dd if=a.out of=/dev/fd0
#==================================================
Boot from the floppy disk. You should see the printed messages. If not, modify
YOUR .c file and try again.
The file ~cs460/samples/lab1.bin.gz is a sample solution.
Download the file. Run gunzip lab1.bin.gz to uncompress it.
Dump it to a floppy disk by
dd if=lab1.bin of=/dev/fd0 bs=1024
Then, reboot from the floppy disk.
To boot the floopy disk under DOSEMU, run
xdosemu -A
!============================ mys.s file ====================================
BOOTSEG = 0x9000 ! Boot block is loaded here.
SSP = 4096 ! Stack pointer at 4KB relative to SS
.globl begtext, begdata, begbss ! these are needed by linker
.globl _setVideo, _diskr, _getc, _putc ! EXPORT
.globl _main, _myprints ! IMPORT
.text ! these tell as:
begtext: ! text,data,bss segments
.data ! are all the same.
begdata:
.bss
begbss:
.text
! this is the entry point
!---------------------------------------------------------------------------------
! Only one SECTOR loaded at (0000:7C00). We shall get entire BLOCK0 to (0x9000,0)
!---------------------------------------------------------------------------------
start:
mov ax,cs
mov ss,ax ! set SS=CS=0x0000
mov sp,#0 ! sp at 0x1000, now we have a stack
mov ax,#BOOTSEG
mov es,ax ! set ES to 0x9000 for memory location (ES,BX)
! call diskr(cyl, head, sector, buf) with (0,0,0,0)
xor ax,ax ! clear AX
push ax ! push 0 for buf=0
push ax ! push 0 for sector=0 (diskr will inc it by 1)
push ax ! push 0 for head=0
push ax ! push 0 for cyl=0
call _diskr ! call diskr() to read 2 sectors to (ES,BX)=(0x9000,0)
! jump indirect to (0x9000, start) to continue execution there
jmpi go_on,BOOTSEG ! CS=BOOTSEG, IP=go_on
go_on:
mov ax,cs ! establish segments CS, DS, SS, again
mov ds,ax ! we know ES,CS=0x9000. Let DS=CS
mov ss,ax ! SS = CS ===> all point at 0x9000
mov sp,#SSP ! SP = SS + 4KB
mov ax, #0x0012 ! color
int 0x10
call _main ! call main() in C
dead: jmp dead ! fall into an infinite loop
!----------------------------------------
! setVideo() : clear screen, home cursor
!----------------------------------------
_setVideo:
mov ax, #0x0012 ! color
int 0x10
mov ax, #0x0200 ! home cursor
xor bx, bx
xor dx, dx
int 0x10
ret
!---------------------------------------
! diskr(cyl, head, sector, buf)
! 4 6 8 10
!---------------------------------------
_diskr:
push bp
mov bp,sp ! bp = stack frame pointer
movb dl, #0x00 ! drive 0=FD0
movb dh, 6[bp] ! head
movb cl, 8[bp] ! sector
incb cl ! inc sector by 1 to suit BIOS
movb ch, 4[bp] ! cyl
mov bx, 10[bp] ! BX=buf ==> memory addr=(ES,BX)
mov ax, #0x0202 ! READ 2 sectors to (EX, BX)
int 0x13 ! call BIOS to read the block
jb error ! to error if CarryBit is on [read failed]
pop bp
ret
!------------------------------
! error & reboot
!------------------------------
error:
mov bx, #bad
push bx
call _prints
int 0x19 ! reboot
bad: .asciz "Error!"
!---------------------------------------------
! char getc() function: returns a char
!---------------------------------------------
_getc:
xorb ah,ah ! clear ah
int 0x16 ! call BIOS to get a char in AX
ret
!----------------------------------------------
! void putc(char c) function: print a char
!----------------------------------------------
_putc:
push bp
mov bp,sp
movb al,4[bp] ! get the char into aL
movb ah,#14
mov bx,#0x000B ! BL=0B => cyan
int 0x10 ! call BIOS to display the char
pop bp
ret
!===========================================================================