#generate 16-bit code .code16 #hint the assembler that here is the executable code located .text .globl _start; #boot code entry _start: jmp _boot #jump to boot code welcome: .asciz "Hello, new World\n\r" #here we define the string enter_number: .asciz "Enter a number: \n\r" lower_msg: .asciz "\nYour number is to low :( \n\r" # 26 higher_msg: .asciz "\nYour number is to high :( \n\r" # 27 winner_msg: .asciz "\nYour are the CAMPION, :D \n\r" # 26 .macro mWriteString str #macro which calls a function to print a string leaw \str, %si call .writeStringIn .endm # function to print the string .writeStringIn: lodsb orb %al, %al jz .writeStringOut movb $0x0e, %ah int $0x10 jmp .writeStringIn .writeStringOut: ret .type get_number, @function get_number: # save state before function push %bp mov %sp, %bp push %bx push %cx # Start of function mWriteString enter_number mov $0, %ah mov $0, %al int $0x16 mov $0x0E, %ah int $0x10 pop %cx pop %bx mov %bp, %sp pop %bp ret .type string_to_int, @function string_to_int: /* Converts a string to an integer. Returns the integer in %rax. * %rax: Address of string to convert. */ push %bp mov %sp, %bp push %bx push %cx mov %ax, %dx cmp $47, %dx jl not_a_num cmp $57, %dx jg not_a_num # I multiply by 10 to shift the number one placement to the right to add the newest integer. sub $48, %dx jmp convertdone # In ascii, numbers start at 0 = 48, 1 = 49, 2 = 50 and so on. So I subtract 48 to get the digit. not_a_num: xor %dx, %dx convertdone: pop %cx pop %bx mov %bp, %sp pop %bp ret _boot: mWriteString welcome guess: call get_number xor %ah, %ah call string_to_int cmp $5, %dx jl if_lower je if_eg jg if_higher if_lower: mWriteString lower_msg jmp guess if_higher: mWriteString higher_msg jmp guess if_eg: mWriteString winner_msg #move to 510th byte from the start and append boot signature . = _start + 510 .byte 0x55 .byte 0xaa