1

I have to extract digit stored in si register. here is my code

lea si, userInput
inc si

mov bx, [si]

mov dx, [si+bx]
add dx, 30h
mov ah, 2h 
int 21h

So i think code works fine if i put hard value in dx register like mov dx, [si+2] but if try to use mov dx, [si+bx] it does not work and does not give ouput as expected

doey doe
  • 13
  • 5
  • I'm not quite clear on what you are trying to do. But there are a few things I notice. For example you are doing `inc si` right after your `lea`. So you are skipping the first byte? Then you do `mov bx, [si]`. That reads 2 bytes from [si] (since bx is 16bits long). I'm not sure what `mov dx, [si+bx]` is supposed to do. If the mov from the line above loads 1234 into bx, then this would read the byte at [si + 1234]. That can't be what you want? Then you do `mov dx, 30h` right before calling int 21. Do you really always intend to print 0? Or did you mean to `add` 30h? – David Wohlferd Nov 11 '18 at 05:36
  • sorry I added `mov dx, 30h` by mistake it should have been `add dx, 30h` so bx contains the length of the address stored in si and I am using it to print specific index – doey doe Nov 11 '18 at 13:54

1 Answers1

0

Assuming your userInput points at the input structure required for DOS's buffered input function 0Ah, these are my recommandations to correct your code:

  • The second byte holds the number of inputted characters. You mistakenly retrieve this as if it were a word.
  • The input consists of characters that are 1 byte wide. You currently retrieve it as if they were 2 bytes.
  • Since the input is already made up of characters, you don't need to do any conversion on it. (The attempt mov dx, 30h) The fact that this character could represent a (numerical) digit, a letter, a punctuation mark, or anything else, doesn't change this.

Your code then becomes:

lea si, userInput
inc si

mov bl, [si]     ;Number of inputted characters
mov bh, 0        ;Need to zero to be able to use the whole address-register BX next

mov dl, [si+bx]  ;Retrieve the last inputted character (right before the terminating CR)
mov ah, 02h 
int 21h          ;Display the character
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • thanks, I think I was putting everything into `bx` register directly that's why it was giving weird results – doey doe Nov 11 '18 at 14:05
  • @doeydoe You can find some additional info about this DOS input mechanism in another post of mine : https://stackoverflow.com/questions/47379024/how-buffered-input-works. First chapter in the answer there. – Sep Roland Nov 11 '18 at 14:09
  • i have one more question i am using this loop to print everything where dx is 1 `loop1: mov dx, [si+bx] cmp dx, 1 je match cmp bx, 1 je endLoop sub bx, 1 jmp loop1 match: mov ah, 2h int 21h jmp loop1 endLoop:` but it is not entering `match` loop when dx is 1 – doey doe Nov 11 '18 at 14:29
  • @doeydoe Please notice that you need to change all of those `DX` 's into `DL`. It's always a single byte! Also I think you want to compare with the **character 1**, so write `cmp dl, '1'` – Sep Roland Nov 11 '18 at 14:36
  • thanks now it is entering loop but it is getting into endless loop `loop1: mov dl, [si+bx] cmp dl, '1' je match cmp bx, 1 je endLoop sub bx, 1 jmp loop1 match: mov ah, 2h int 21h sub bx, 1 jmp loop1` – doey doe Nov 11 '18 at 14:43
  • @doeydoe Beware for the endless loop if a match is found! Don't jump back to *loop1*, but rather jump back to the instruction that compares `bx` to 1. – Sep Roland Nov 11 '18 at 14:44
  • @doeydoe In your last draft, the second `sub bx, 1` can't stay. – Sep Roland Nov 11 '18 at 14:51
  • i had removed `sub bx, 1` i tried to using `ret` instead of `jmp` but it takes input again and again – doey doe Nov 11 '18 at 14:58
  • @doeydoe You can't just choose an instruction at random! Insert an extra label between `je endLoop` and `sub bx, 1`, and then jump to that label from right after the `int 21h` instruction. – Sep Roland Nov 11 '18 at 15:03