0

I am beginner in assembly and I need help for this conversion.The code below should convert from a string read from keyboard with the interrupt 01h.I know it is incorrect but can you help me identify the mistake?

mov dx,0 
convert:
    sub al,48 ;to covert to int
    mov bl,al ;in bl will be the digit read 
    mov ax,dx
    mul ten   ;ax will store the old result multiplied by 10
    mov bh,0
    add ax,bx
    mov dx,ax 
Noname
  • 41
  • 1
  • 1
  • 10
  • Read this -> http://stackoverflow.com/a/19462538/4117717 – Ellipticat Dec 30 '14 at 09:58
  • 1
    This is not a good question. In fact, it is not a question at all. Please read this first: http://stackoverflow.com/help/how-to-ask – Ruud Helderman Dec 30 '14 at 10:00
  • What is the problem you are having? Where is the pointer to the string? What is the expected output, and what is the output you are getting? – Jonathon Reinhart Dec 30 '14 at 11:47
  • i don't understand what's going on in that code sorry.I wanted to make a loop there or a jump but the operand type don't mach i think.When i multiply by 10 ax,the result will be stored in dx:ax and i don't know how to handle this – Noname Dec 30 '14 at 12:12
  • now is a question,Ruud! – Noname Dec 30 '14 at 12:22
  • "I know it is incorrect" is not a good problem description; consequently "can you help me identify the mistake" is not a good question. But I am in a good mood and I managed to compose an answer (HTH), based on info you provided in your comments. Please edit your question to include the essential parts of the comments. – Ruud Helderman Dec 30 '14 at 16:38
  • I'm so sorry I don't know how to ask a good question... Thanks for helping me! – Noname Dec 30 '14 at 18:40

2 Answers2

1
mul ten   ;ax will store the old result multiplied by 10  

From the comment I understand that ten is a word sized variable containing the value 10.
This means that the multiply is word sized and thus overwrites DX.
Solution : Change DX to p.e. CX

mov cx,0 
convert:
sub al,48 ;to covert to int
mov bl,al ;in bl will be the digit read 
mov ax,cx
mul ten   ;ax will store the old result multiplied by 10
mov bh,0
add ax,bx
mov cx,ax 
Fifoernik
  • 9,779
  • 1
  • 21
  • 27
  • If you load new characters into a different register (not AX), the total can stay in AX for `total = total*10 + (char - '0')` across loop iterations. This appears to have way move `mov` instructions than necessary. And you can even use DX for the temporary for zero-extending a new character, after `mul` clobbers it. – Peter Cordes Dec 06 '22 at 22:14
  • [connecting integer multiplication in assembly x86](https://stackoverflow.com/a/74709668) has a loop that uses 16-bit multiply and add. – Peter Cordes Dec 06 '22 at 22:57
0

mul comes in 2 flavors:

  • multiply two 8-bit values (AL and mul's operand); store the 16-bit result in AX
  • multiply two 16-bit values (AX and mul's operand); store the 32-bit result in DX AX

Your question is a bit vague, but I assume you want the first flavor, but instead you found yourself faced with the second.

To tell the assember you want the first flavor, give mul an operand that is unmistakably 8-bit. One way that certainly works on all assemblers, is to use an 8-bit register, for example BH (I chose that one because it is obvious its value is irrelevant at the time of mul since it is overwritten shortly after).

sub al,48   ; to covert to int
mov bl,al   ; in bl will be the digit read 
mov ax,dx

mov bh,10   ; use BH to hold factor 10
mul bh      ; multiply AL by BH; the product is stored in AX; DX is unaffected

mov bh,0
add ax,bx
mov dx,ax 

EDIT:
I just realized this will limit the range of numbers that can be entered to 0...255, which is probably not what you want. Use user3628942's solution instead; it allows you to enter numbers up to 65535.

As often, there are other ways. Below is a solution that uses add instead of mul. Many years ago, this was a popular trick for processor architectures where mul was either an expensive (i.e. slow) instruction, or totally absent. Works for numbers up to 65535; silently wraps to zero for higher numbers.

sub al,48    ; ASCII value --> numeric value
mov ah,0     ; AX = numeric value of digit
add dx,dx    ; DX = 2 * original DX
add ax,dx    ; AX = 2 * original DX + digit
add dx,dx    ; DX = 4 * original DX
add dx,dx    ; DX = 8 * original DX
add dx,ax    ; DX = 10 * original DX + digit
Ruud Helderman
  • 10,563
  • 1
  • 26
  • 45