Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Need help as soon as possible

Hi guys, i am a beginner in assembly and i need to write code which lets you to input string and prints the position of every number. I know how to write code to imput string and find out if the symbol is number or not, but i have no idea how to count the position and print it. Can anybody help me?

Comments

  • thatsmethatsme Posts: 8Member
    .model small
    .stack 100h
    .data

    msg DB "Input string", 13, 10, "$"
    maxlength db 254
    length db "?"
    string db 254 dup ("$")
    enter db 13, 10, "$"


    .code
    start:

    mov ax, @data
    mov ds, ax

    lea dx, msg
    mov ah, 9
    int 21h

    lea dx, maxlength
    mov ah, 10
    int 21h

    xor cx, cx

    mov cl, [length]

    lea si, string

    lea dx, eol
    mov ah, 9
    int 21h

    cycle:
    lodsb
    cmp al, 20h
    jne cycle2
    jmp endofcycle

    cycle2:
    cmp al, 30h
    jl endofcycle
    cmp al, 39h
    jg endofcycle
    jmp endofcycle

    ciklopabaiga:
    loop cycle

    ...


    end start
    by the way, thats my code so far
  • anthrax11anthrax11 Posts: 511Member
    Hi,
    can you explain what you mean by printing the position of each number?
    Does it mean that when entering "9ea3a", it should print out "1, 4"?

    One thing to note is that interrupt calls tend to overwrite registers, so you should print eol before setting up cx and si.
  • thatsmethatsme Posts: 8Member
    yes, i meant that, so could you finish my code, plz, this would be a big favour for me
  • anthrax11anthrax11 Posts: 511Member
    I've optimized it a bit, because there's not much use in learning asm unless you're after the fastest and smallest code. Anyway, here's how I would do it, ask if you have any questions.
    [code]
    .model small
    .stack 100h
    .data

    msg DB "Input string"
    eol db 13, 10, "$"
    maxlength db 254
    str_len db ?
    string db 254 dup (?)
    num_buffer db 7 dup(?)


    .code
    start:

    mov ax, @data
    mov ds, ax

    mov dx, offset msg
    mov ah, 9
    int 21h

    mov dx, offset maxlength
    mov ah, 10
    int 21h

    mov dx, offset eol
    mov ah, 9
    int 21h


    cld
    xor cx, cx
    mov si, offset string

    cycle:
    cmp cl, [str_len]
    je exit

    ; increment position counter
    inc cl

    lodsb
    cmp al, '0'
    jl cycle
    cmp al, '9'
    jg cycle

    call print_num ; print position
    jmp cycle

    exit:
    mov ax, 4c00h
    int 21h


    ; Prints the number stored in cl
    print_num:
    call get_num_len

    ; end the string with ",$"
    mov di, offset num_buffer
    add di, ax
    mov word ptr [di], '$,'

    mov al, cl
    mov bl, 10
    div_loop:
    xor ah, ah
    dec di
    div bl
    add ah, '0'
    or al, al
    mov byte ptr[di], ah ; store the reminder
    jnz div_loop ; loop until quotinent(al)=0

    ; print num_buffer
    push cx
    push si
    mov dx, di
    mov ah, 9
    int 21h
    pop si
    pop cx

    ret


    ; Returns the length of cl
    ; if it were an ascii string
    get_num_len:
    mov al, cl
    mov bl, 10
    xor dx, dx

    get_len_loop:
    xor ah, ah ; ah = 0
    div bl ; al = ax/10
    inc dx
    or al, al ; loop until quotinent=0
    jnz get_len_loop

    mov ax, dx
    ret

    end start
    [/code]
  • thatsmethatsme Posts: 8Member
    1.can you tell what does "cld" mean?
    2. can you explain step by step the instructions that you do from get_num_len and why
    3.How to make code stop couting a space as a position? for exampe: input k2mm 1k, rezult: 2, 5(not 6)
  • anthrax11anthrax11 Posts: 511Member
    1. Cld clears the direction flag. The direction flag controls the behaviour of lodsb. If it is cleared, then si is incremented after loading the byte to al, otherwise si is decremented and the string is handled backwards. In 99% of cases you can assume that the flag is already cleared, because it's a convention to always clear it after setting it. It doesn't hurt to clear it anyway as a precaution, cld only takes one byte.

    2. Get_num_len is a function that returns the length of the number if it were written as an ascii string. If the number is 7, then 1 is returned, if it's 45, then 2 is returned, if 566, then 3, and so on. This is needed, because the conversion of a number to string always starts from the smallest digit, but we humans write the smallest digit to the end. By knowing how long the string will be, we can write the number out starting from the end and moving left to where the largest digits are.

    The conversion can also be implemented using a stack, but it's a bit more complex.
    [code]
    ; Returns the length of cl
    ; if it were an ascii string
    get_num_len:
    mov al, cl ; save cl in al
    mov bl, 10 ; this is the base of the number, 10 is for decimal
    xor dx, dx ; dx=0, dx is the digit counter

    get_len_loop:
    xor ah, ah ; ah = 0
    div bl ; al = ax/10, divides ax by bl, which is 10
    ; returns al=quotinent, ah=remainder
    inc dx ; dx = dx + 1, one more digit
    or al, al ; compare al against 0
    jnz get_len_loop ; loop until quotinent=0

    mov ax, dx ; return the counter in ax
    ret
    [/code]
    Here's what's happening. Let's take the number 245. Dividing by 10 we get the quotinent 24 and the remainder is 5. In the conversion loop we would take the 5 from the ah register and store it in the buffer as the smallest digit, but here we just want to know how many digits there are. Anyway, we increment the counter, because every number has at least one digit. Next we compare the quotinent to 0. Since it is 24, we know that there are more digits to come, so we loop. Now dividing 24 by 10, we get quotinent=2, remainder=4. Still the quotinent is 2, so there's one more digit. After the final division we have quotinent=0, remainder=2 and the counter(dx) is 3.

    3. Simply compare al to ' ' after lodsb and exit if it's equal.
    [code]
    lodsb
    cmp al, ' '
    je exit

    cmp al, '0'
    ...
    [/code]
Sign In or Register to comment.