1

I'm trying to do the following, but I'm having some trouble, and the only code I find on the web is for transforming strings into a number (basicly atoi), but I need something slightly different, e.g:

num1 Db '60','30'
num2 Db '2', '3'
num3 Db '*', '*'

Basicly I only need to transform the chars in the vector into numbers (separately), so I can do the operation marked by num3 with num1 and num2 as operators, as an example, I'll use my function that multiplies two numbers. What I tried was:

MOV AX, DADOS
MOV DS, AX
MOV CX, 2
cycle:      
    CMP num3[si], 2Fh
    JE DIVISAO
    CMP num3[si], 2Ah
    JE MULTIPLICA
    CMP num3[si], 2Bh
    JE SOMA
    CMP num3[si], 2Dh
    JE SUBTRACAO
    inc si
    loop cycle

    JMP FIM

The multiply function:

MULTIPLICA PROC
    PUSH AX
    MOV AH, 0
    SUB num1[si], 48
    MOV AL, num1[si]
    SUB num2[si], 48
    IMUL num2[si]
    MOV DX, AX
    POP AX
    RET 
MULTIPLICA ENDP

I thought I only needed to subtract 48 to each position to make it into the correspondant number, but I guess there's something more to it. Thanks. Edit: Did some ajustments, found out that it's only multiplying the first character, e.g: instead of 60*2, it's only doing 6*2

Zetsuno
  • 97
  • 1
  • 9

2 Answers2

2

Yes, there definitely is something more to it. To turn a string into a byte, you can use something like this

; INPUT esi = a null-terminated string
; OUTPUT al = the number
str2byte:
    push cx
    mov cx, 0x0a00
    xor al, al
    .loop:
        mul ch
        mov cl, byte [esi]
        inc esi
        test cl, cl
        jz .end

        sub cl, 0x30
        add al, cl
        jmp loop
    .end:
    pop cx
    ret

... and to do the multiplication

num1 db '60', 0
num2 db '2', 0
multiply:
    mov esi, num1
    call str2byte
    mov ah, al

    mov esi, num2
    call str2byte

    imul ah

    ; the result is in AX
    ret

str2byte function requires esi to contain a null-terminated string to allow numbers like 100 or 255, and therefore use the full range of a byte.

Edit:

If you were to use more elements, it would be only better to either use separate labels for all of them, e.g.

num1: db '60', 0
num2: db '4', 0
num3: db '7', 0
...

... or to align them, so you could smoothly get through

numbers: ; all of them are aligned to 4 bytes
    db '60', 0, 0
    db '4', 0, 0, 0
    db '120', 0
    ...

iterate:
    mov esi, numbers
    .loop:
       ; do something, like multiplying

       add esi, 4 ; increment by four bytes = one number
       jmp .loop

Edit 2:

However, the most elegant way to get through this kind of strings is to start where you've ended. That means, that you can use a chain for null-terminated string in a loop.

numbers:
    db '60', 0
    db '4', 0
    db '120', 0
    ...
    db '13', 0
    db 0

iterate:
    mov esi, numbers
    .loop:
        ; do something, let esi to be pointed at the beginning of every new string
        cmp byte [esi], 0x0 ; two zeroes can mean an end of strings / file
        jnz .loop ; again

Please note that

db 60

takes a single byte, while

db '60'

takes two bytes: one for '6' (0x36), and one for '0' (0x30)

user35443
  • 6,309
  • 12
  • 52
  • 75
  • if there are more elements in num1, as I mentioned in my example, I only need to add the index to mov esi, num1[si] and add a 0 to the end of the string, right? (and to num2 aswell) – Zetsuno May 31 '15 at 15:12
  • @user35443 Your *str2byte* routine still needs a way to exit. – Sep Roland May 31 '15 at 15:19
  • @user35443 I won't be able to use separate labels to all of them, because the vector has the input of a .txt file, in which the numbers are sequentially introduced into the vector – Zetsuno May 31 '15 at 15:21
  • @user3144770 thanks, I forgot one `jz` there and one `inc` for esi – user35443 May 31 '15 at 15:21
  • @Zetsuno in that case you may use the second approach, or a third one (wait for edit) – user35443 May 31 '15 at 15:22
  • @user35443 I don't think I will be able to modify the code that transfers the .txt input into the vectors, it was provided by my college professor, and I don't have enough assembly knowledge to modify it to what I want, so I don't think I could do the change that aligns to 4 bytes... sorry – Zetsuno May 31 '15 at 15:27
  • @Zetsuno That's why I added the Edit2, have a look. The format you've given is rather illogical, because there's no way to find out what the length of a `'string'` is, when they aren't null-terminated nor fixed in their length. Are you sure that's exactly the format? No `"` or `0`es at the end? – user35443 May 31 '15 at 15:32
  • I think so, but I'm contacting my professor for more info, thanks for all your help tho, gonna try it then i'll net you know how it went! – Zetsuno May 31 '15 at 15:35
0
num3 DW '*', '*'

You need to define num3 as byte because the inc si will give garbage on the 2nd iteration.

MOV DS, AX

Move this one outside the loop because AX will probably not have a segment value on subsequent iterations.

If the multiplica proc delivers a result in CX how then can you hope to continu the loop ?

Sep Roland
  • 33,889
  • 7
  • 43
  • 76