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

converting a vector of chars to int in assembly

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

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

基本上我只需要将向量中的字符(分别)转换为数字,所以我可以用num1num2num3标记的操作 作为运算符,例如,我将使用我的函数将两个数字相乘。 我试过的是:

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

num3 DW '*', '*'

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

MOV DS, AX

将这个移出循环,因为 AX 在后续迭代中可能没有段值。

如果 multiplica 过程在 CX 中提供了结果,那么您如何希望继续 loop

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

; 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 包含一个以 null 结尾的字符串以允许像 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)