在汇编中将字符向量转换为 int
converting a vector of chars to int in assembly
我正在尝试执行以下操作,但遇到了一些麻烦,我在网上找到的唯一代码是将字符串转换为数字(基本上是 atoi),但我需要一些稍微不同的东西,例如:
num1 Db '60','30'
num2 Db '2', '3'
num3 Db '*', '*'
基本上我只需要将向量中的字符(分别)转换为数字,所以我可以用num1
和num2
做num3
标记的操作
作为运算符,例如,我将使用我的函数将两个数字相乘。
我试过的是:
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 结尾的字符串以允许像 100
或 255
这样的数字,因此使用一个字节的完整范围。
编辑:
如果您要使用更多元素,最好为所有元素使用单独的标签,例如
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
)
我正在尝试执行以下操作,但遇到了一些麻烦,我在网上找到的唯一代码是将字符串转换为数字(基本上是 atoi),但我需要一些稍微不同的东西,例如:
num1 Db '60','30'
num2 Db '2', '3'
num3 Db '*', '*'
基本上我只需要将向量中的字符(分别)转换为数字,所以我可以用num1
和num2
做num3
标记的操作
作为运算符,例如,我将使用我的函数将两个数字相乘。
我试过的是:
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 结尾的字符串以允许像 100
或 255
这样的数字,因此使用一个字节的完整范围。
编辑:
如果您要使用更多元素,最好为所有元素使用单独的标签,例如
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
)