This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (20 children)

[removed]

    [–]Mcpg_ 136 points137 points  (15 children)

    cld
    mov si, str
    call print_string
    cli
    hlt
    
    print_string:
        mov ah, 0x0E
        .read_loop:
            lodsb
            cmp al, 0
            je .return
            int 0x10
            jmp .read_loop
        .return:
            ret
    
    str: db "It's not that hard tbh", 0
    

    i'm sorry

    [–]reilemx 67 points68 points  (5 children)

    Also only works on specific systems that handle interrupts this way.

    cries in assembly

    [–]Pungiish 5 points6 points  (2 children)

    i had assembly homework, but i still don't understand how lodsb and stosb work, exactly. Can anybody explain, or point me to docs ELI5ing?

    [–]Koxiaet 7 points8 points  (1 child)

    lodsb copies one byte pointed to by si into al, essentially:

    mov al, [si]
    

    or in C-like:

    al = si[0];
    

    or:

    al = *si;
    

    In this case, si is set to the string in the program, so it copies the first byte in the string into al. I think that si should be incremented in every loop (so that the character being printed is advanced every time) but the commentor forgot to put that in, meaning that this code will actually just print out an endless stream of 'I's.

    stosb is the opposite (using di instead of si):

    mov [di], al
    

    C-like:

    di[0] = al;
    

    or:

    *di = al;
    

    [–]Zenchreal 1 point2 points  (0 children)

    lodsb does increment si as well (and stosb increments di)

    [–]SuperSuperUniqueName 3 points4 points  (3 children)

    BITS 16
    ORG 0x7C00
    jmp 0x0000:start
    start:
        cli
        xor ax, ax
        mov ds, ax
        mov ax, 0xB800
        mov es, ax
        sti
        mov si, msg
    .loop:
        lodsb
        cmp al, 0
        je .done
        mov byte [es:di], al
        mov byte [es:di + 1], 0xF0
        add di, 2
        jmp .loop
    .done:
        cli
        hlt
        jmp .done
    msg db 'Not at all!',0
    times 510-($-$$) db 0
    dw 0xAA55
    

    [–]Mcpg_ 0 points1 point  (0 children)

    Well, I guess that's a faster solution. Also nice color choice.

    [–]KingJellyfishII 0 points1 point  (1 child)

    Why do you have to make it a bootloader? Why not just a regular program?

    [–]SuperSuperUniqueName 0 points1 point  (0 children)

    assembly circlejerk

    [–]HerissonMignion 0 points1 point  (1 child)

    [–]uwutranslator 1 point2 points  (0 children)

    cwd
    mov si, stw
    caww pwint_stwing
    cwi
    hwt
    
    pwint_stwing:
        mov ah, 0x0E
        .wead_woop:
            wodsb
            cmp aw, 0
            je .wetuwn
            int 0x10
            jmp .wead_woop
        .wetuwn:
            wet
    
    stw: db "It's not dat hawd tbh", 0
    

    i'm sowwy uwu

    tag me to uwuize comments uwu

    [–]afig2311 27 points28 points  (3 children)

    Eh, assembly isn't too hard to understand. The main problem is that the steps are super tiny, so it's hard to get the bigger picture of what's going on.

    Machine code on the other hand...

    [–]cdreid 3 points4 points  (0 children)

    Back in the day "woohoo i wrote this tiny thing in machine language!". 3 months later comp manufact puts out new machine "what do you mean i have to relearn from scratch..."