0

I am using nasm to print one string at a time but it prints two string at a time, i have added null character to the end and i am comparing the null character to check for the end of the string but both the strings end up getting printed even when i ask for only one of them.

[org 0x7c00]

mov bx, HELLO_MSG
call print_string

mov bx, GOODBYE_MSG

jmp $

%include "print_string.asm"

;Data
HELLO_MSG:
db 'Hello, World!',0

GOODBYE_MSG:
db 'GOODBYE!',0

times 510-($- $$) db 0
dw 0xaa55

The other file print_string.asm

print_string:
pusha
cld
mov ah,0x0e

 config:    mov al,[bx]
            ;Comparing the strings
            mov cx,[bx]
            cmp cx,0x00 ;Comparing for null
            jne print
je end

print:  int 0x10
        add bx,1
        jmp config

end:    popa
        ret
Bipul Adh
  • 103
  • 1
  • 2
  • 6
  • 2
    `mov cx,[bx]` This instruction reads the *WORD* at bx (ie 2 bytes). Since there is no WORD that is 0, this loop never ends. – David Wohlferd Oct 22 '17 at 06:29
  • 1
    Just an observation. `pusha`/`popa` is an 80186 instruction. If writing a bootloader that may target a wide variety of hardware one should probably consider 8086 instructions only. Of course if the intent is to bootstrap a protected mode kernel then it is a non issue. You should also explicitly set your DS segment register and use CLD to ensure string instructions move in the forward direction. Thes are observations on top of the existing answer. – Michael Petch Oct 22 '17 at 07:00
  • @DavidWohlferd Thanks for the insight. I changed that code to. `config: mov al,[bx]` `;Comparing the strings` `cmp byte [bx],0x00 ;Comparing for null` `jne print` `je end` It's working now – Bipul Adh Oct 22 '17 at 07:30

1 Answers1

2
; ds:si = asciiz string pointer
print_string:
    pushf            ; store everything to be modified
    push ax
    push bx
    push si
    cld
    mov ah,0x0e
    xor bx,bx        ; bh (page) = 0, bl (color in gfx modes only)
 print_string_loop:
        lodsb
        ; check for null-terminator of string
        test al,al
        jz  print_string_end
        int 0x10
        jmp print_string_loop
 print_string_end:
    pop  si      ; restore everything
    pop  bx
    pop  ax
    popf
    ret

; other code must be adjusted to put pointer into SI, not BX!

This shows common x86 asm idiom to test for zero value.

And I moved the string pointer into si from bx, because then I can use lodsb to load the al (with incrementation of si included), and to avoid bx, as bh and bl are input arguments for int 10h,ah=0Eh. So your old code displays anything sort of by accident, if your string address would load bh with some valid page number which is not visible (by default page 0 is visible in text mode), you wouldn't see your letters on screen.

Plus you surely are not in such hurry, that you can't keep your labels meaningful, and stick with some indentation style (I tried to guess what it is in my answer, not sure if I nailed it). I know it's sort of difficult to keep it tidy when you are just experimenting, but before posting SO question it's probably good to take a step back and clean up as much as possible to get Minimal, Complete, and Verifiable example, make the reading of source as easy as possible to attract the biggest amount of people to try to check for your problems. In the long run cleaning up after your code works will help to save also your time.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • Sorry I meant to put my comment under the question and not your answer. – Michael Petch Oct 22 '17 at 07:03
  • 1
    @MichaelPetch fixed it to ordinary push/pop and thanks to it I realized I don't set `bx` in my answer, which was sort of bug (or feature, as then it was argument for caller, but unplanned feature). – Ped7g Oct 22 '17 at 07:04
  • 1
    3 hours after getting your answer the OP asked another question for which I wrote an [answer](https://stackoverflow.com/questions/46872873/nasm-module-to-convert-hex-into-string-and-print-it-out-assembles-but-not-worki/46876100#46876100). He continues to use his problematic *print_string*. Makes me wonder why we even bother... – Sep Roland Oct 22 '17 at 19:24
  • @SepRoland eventually it will bite him, he probably still thinks that "when does output correct thing, it works", seems kind of natural mistake of new asm programmers to be so naive... :) And the experience is not passable, if they would see the bugs I have seen over the years... :) but it's not possible to show them, they will have to hit their own. – Ped7g Oct 22 '17 at 20:55