在汇编中将字符向量转换为int

时间:2015-05-31 14:52:45

标签: assembly x86 x86-16

我尝试执行以下操作,但我遇到了一些麻烦,我在网上找到的唯一代码是将字符串转换为数字(基本上是atoi),但我需要一点点不同的,例如:

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

基本上我只需要将矢量中的字符转换为数字(单独),因此我可以使用num3num1执行num2标记的操作 作为运算符,作为一个例子,我将使用我的函数乘以两个数字。 我试过的是:

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

乘法函数:

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

我认为我只需要将48减去每个位置以使其成为对应的数字,但我想还有更多的东西。谢谢。 编辑:做了一些调整,发现它只是乘以第一个字符,例如:而不是60 * 2,它只做6 * 2

2 个答案:

答案 0 :(得分:2)

是的,肯定还有更多内容。要将字符串转换为字节,您可以使用类似

的内容
; 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

...并进行乘法

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函数要求esi包含以空字符结尾的字符串,以允许使用100255等数字,因此使用整个字节范围。

修改

如果您要使用更多元素,那么为所有元素使用单独的标签会更好,例如

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

...或者对齐它们,这样你就可以顺利通过

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

编辑2:

然而,通过这种字符串的最优雅方式是从你结束的地方开始。这意味着,您可以在循环中使用链以空终止字符串。

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

请注意

db 60

只需一个字节,而

db '60'

需要两个字节:一个用于'6'(0x36),一个用于'0'(0x30

答案 1 :(得分:0)

num3 DW '*', '*'

您需要将 num3 定义为byte,因为inc si将在第二次迭代时产生垃圾。

MOV DS, AX

将此移动到循环外部,因为AX在后续迭代中可能没有分段值。

如果 multiplica proc在CX中提供结果,那么您是否希望继续loop