如何在 tasm 上编写从数值到字符串值的转换器?

问题描述 投票:0回答:1

我需要使用 TASM 执行一些任务,但为此我需要使用输入数字。 因此,首先我尝试在控制台中输入数字,然后将此字符串值转换为数值,然后将此数值转换回字符串值以将其输出到控制台。我只是想确定转换器工作正常。 这可能听起来很愚蠢('^'),但这样的检查对我的实际任务很有用

这是一个转换器,至少执行我所有其他选项的最小部分功能:c 它可能仅适用于 0 到 9 的数字,但不适用于更高的数字。 结果在图像上(首先是我们的 inpt 数字,即字符数量,而不是我们转换后的输入数字。第一行和第二行必须相等)

mov ah, 0
mov si, offset counter_buffer 
push cx
convert_counter_to_ascii:
    mov dx, 0
    mov ax, cx
    mov bx, 10
    div bx
    add dl, '0'
    dec si
    mov [si], dl
    mov cx, ax
    cmp cx, 0 
    jnz convert_counter_to_ascii

    mov ah, 09h
    mov dx, si
    int 21h

这是我查看上下文的完整程序:

assume cs: code, ds: data, ss: stck
code segment
begin:
    mov ax, data
    mov ds, ax

    ;buffered input
    mov ah, 0ah
    mov dx, offset first_input
    int 21h

    ;finding the end of an input string
    mov bx, 0
    mov bl, [first_input + 1]
    mov first_input[bx + 2], '$'
    
    mov ah, 02h
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h

    ;set index counter
    mov di, 0

;counting the amount of input characters. 
;for example: 234 -> total = 5 characters,
;because there're two control bytes in the beginning of buffered input
count_characters:
    mov al, first_input[di]
    cmp al, '$'
    je end_count
    inc di
    jmp count_characters

end_count:
    ;just saving the amount of input characters
    mov cx, di

    ;subtract two, because i'm only interested in numeric characters
    ;without first 2 control bytes
    sub cx, 2
;==================================================================================
;it's a converter of the numeric value of characters amount to string. 
;here i'm going just to check which value i'm actually getting, after "count_caharacters" cycle
;just to be sure that there isn't any mistake and see the result on the console

    mov ah, 0
    ;set si in the beginning of array "counter_buffer", where i'm going to
    ;save string value of counter value.
    mov si, offset counter_buffer 

    push cx

;i don't really sure that this converter is actually right,
;to say exactly it's probably works only for values from 0 to 9,
;but not higher. or not... help ( т _т)
convert_counter_to_ascii:
    mov dx, 0
    mov ax, cx
    mov bx, 10
    div bx
    add dl, '0'
    dec si
    mov [si], dl
    mov cx, ax
    cmp cx, 0 
    jnz convert_counter_to_ascii

    mov ah, 09h
    mov dx, si
    int 21h

;end of converting the numeric value of counter to string value
;=====================================================================================

    mov ah, 02h
    mov dl, 0dh
    int 21h
    mov dl, 0ah
    int 21h

    pop cx

    ;subtracting one from the amount of characters 
    ;because i'm going to count the power of 10
    ;for example input: 234 => cx = 3
    ;234 = 200 + 30 + 4
    ;and because 4 (the last digit) doesn't multipling by any power of 10, 
    ;we are subtracting one character from cx => 
    ;cx = 2 => 10 ^ 2 = 100, and we will get the highest power of 10.
    sub cx, 1
    push cx
    
    ;if the input had only one numeric digit, after subtracting 
    ;1 from cx, we will get zero
    ;so here we just check it
    cmp cx, 0
    je just_one_digit
    
    cmp cx, 0
    jne pow_loop

;here we start the cycle to find the highest power of 
;10 of the input number (for 234 it's 10^2)
;works correctly till power up to 10^2 (only for three digit number), 
;but for current task it's ok
pow_loop:
    mov al, [digit_saver]
    mov bl, 10
    mul bl
    mov [digit_saver], al
    loop pow_loop

    pop cx

    ;returning the full amount of characters in cx by adding 1
    add cx, 1
    push cx

    ;di saves the amount of characters(address of last numeric character)
    mov di, cx
    ;we set index in 2 to avoid the first two control bytes, 
    ;and start converting numeric characters to it's actual numeric values
    mov si, 2

convert_string_to_number:
    ;check each element of input array
    mov al, first_input[si]
    ;we need to check that we're not going to multiply the last 
    ;digit by any power of 10, that's why
    ;we need this compare instruction.
    cmp si, di
    je just_one_digit
    inc si
    ;to get the actual numeric value from string value we need to 
    ;subtract ASCII code of '0' from it
    sub al, '0'
    ;mov the power of ten to bl, and then multiply the current numeric value to this power
    mov bl, [digit_saver]
    ;this instruction is multiplying the stored power of 10 in bl by the numeric value in al
    ;the final result is stored in al (as far as i understand multiplying)
    mul bl
    ;then i have a variable "real_first_number" which will store the 
    ;final summ (this sum: 200 + 30 + 4)
    mov bh, [real_first_number]
    ;add the result of multiplying to bg
    add bh, al
    ;set the value in bh back to "real_first_number"
    mov [real_first_number], bh
    loop convert_string_to_number
 
;it's a mark to sum the last digit, that doesn't need multiplying by power of 10
just_one_digit:
    ;cx saved the amount of numeric characters except first two control bytes
    mov si, cx
    ;here we add this two control bytes, to know exactly the position of this last digit
    ;(position of the last element)
    add si, 2
    ;then we convert it to numeric value
    mov al, first_input[si]
    sub al, '0'
    ;add to result sum. and now we have our entered number in numeric form
    mov bh, [real_first_number]
    add bh, al
    mov [real_first_number], bh


    ;here starts converiting this number that is in numeric form, 
    ;back to string, to output it to the console
    mov ah, 0
    ;array to save string value of this number
    mov si, offset first_number_buffer

    mov al, [real_first_number]
;and here is starting the converter in which i'm not sure.
;for some reason as i said above it works for numbers from 0 to 9,
;but if values os higher  - it brokes ( т _т) 
convert_counter_to_asc:
    mov dx, 0
    mov bx, 10
    div bx
    add dl, '0'
    dec si
    mov [si], dl
    mov cx, ax
    cmp cx, 0 
    jnz convert_counter_to_asc

    mov ah, 09h
    mov dx, si
    int 21h

    mov ax, 4C00h
    int 21h
code ends

data segment
    first_input db 10, ?, 10 dup (?)
    real_first_number db 0
    first_number_buffer db 6 dup ('$')

    counter_buffer db 6 dup('$')

    digit_saver db 1
data ends

stck segment stack
    db 256 dup(?)
stck ends

end begin```
assembly x86-16 tasm
1个回答
0
投票

没错,数值被转换为字符串值了

.model small
.data 
    output_buffer db 10 dup(" ")  
.stack
  db 256 dup (?)
.code
  mov ax, @data    
  mov ds, ax
    
  mov al, 234
  mov cx, 3
  mov di, cx
  mov output_buffer[di], '$'

;before first iteration the value in al = 234
;and output_buffer[3] = '$'

;after first iteration the value in al = 23, and the value in dl = 4
;and output_buffer[2] = '4'
;after second iteration the value in al = 2, and the value in dl = 3
;and output_buffer[1] = '3'
;after third iteration the valuue in al = 0, and the value in dl = 2
;and output_buffer[0] = '2'
convert_integer_to_string:
  dec di
  mov ah, 0
  mov dx, 0
  mov bl, 10
  div bl
  ;add dl, '0'
  add ah, '0'
  ;mov output_buffer[di], dl
  mov output_buffer[di], ah
  cmp di, 0
  jne convert_integer_to_string

  ;and the result is: output_buffer = "234$" 
  mov ah, 09h
  mov dx, offset output_buffer
  int 21h

  mov ah, 4Ch   
  int 21h      
end
© www.soinside.com 2019 - 2024. All rights reserved.