转到程序集中用户输入的末尾



这是家庭作业,我需要转换64位(20个字符的用户输入)。十进制到十六进制

我的第一步是将char转换为十进制,因此我需要将用户输入的ASCII转换为十进制。

如何移动和获取用户输入的字符串的最后一个值组装中?

假设我要一个数字,为了简单起见,用户输入了121,我知道这是ASCII 31,32,31字符,我需要先将其转换为十进制,所以我想取最低有效位,即从最右边到最高有效位的数字(从右到左)。

这是我的代码:

initialize:
xor rax, rax                 ; initializes rax
mov rcx, 0                   ; initialize rcx
mov rbx, 0                   ; clear register to store result
mov rdx, 1                   ; initliaze rdx to base 10 (10^0)
convertInputToDigits:
mov rcx, [count]            ; initialize count
mov rsi, buf                ; point to start of buffer
add rsi, [count]            ; move to end of user input, this part may be wrong
mov rbx, [rsi-1]              ; move the first rightmost number in rbx
sub rbx, '0'                ; subtract hex value 30 for each character
; to get decimal value 0-9
mov rax, [rbx]              ; move the result in rax
mul rdx                     ; multiply result, power of 10(rax*rdx)
add rbx, rax                ; stores the total in rbx
dec rsi                     ; decrement up until first character
cmp rsi, 0                  ; check if we are at the end of input/converted all input to decimal
je convertToHex             ; if so jump to conversion
mov ax, [rdx]            ; move value of rdx to ax
imul ax, 10              ; updates to the next power by 10*1 (10^1, 10^2)
jmp convertInputToDigits    ; if not, loop again

我做错了什么?该如何解决?

谢谢!

第页。S.output: 6296.不知道它是怎么得到的,但肯定不是我需要转换的十进制121。

我想说的太多了,无法放在评论中。但既然我不打算为你做家庭作业,让我们看看我是否能解释这些问题,然后你就能解决它们。

因此,从顶部开始:

initialize:
xor rax, rax                 ; initializes rax

这个"初始化"对rax有什么作用?你知道吗?如果这是课堂,我会等你回答,但我假设你已经知道它将rax设置为零。考虑到这一点,这条线对rcx有什么作用?

mov rcx, 0                   ; initialize rcx

很明显,它将其设置为零。那么…为什么要用两种不同的方法将寄存器设置为零呢?读起来有点困惑。此外,一个可能比另一个更有效率,那么为什么不总是使用最高效的呢?哪一个最有效?看看这个。

继续:

mov rbx, 0                   ; clear register to store result
mov rdx, 1                   ; initliaze rdx to base 10 (10^0)

我们将忽略拼写错误。。。

convertInputToDigits:
mov rcx, [count]            ; initialize count

这不会"初始化"计数。它将count指定的内存中的当前值读取到rcx中。希望计数是8字节长。这就是rcx的大小,也就是mov要读取的字节数。你没有显示count被分配了一个值,但我希望你这样做。否则rcx将只包含垃圾。

mov rsi, buf                ; point to start of buffer
add rsi, [count]            ; move to end of user input, this part may be wrong

我不清楚你为什么在循环中有这些线。当您到达循环的底部并跳回convertInputToDigits时,您不想将rsi重置为buf并再次添加"count"。您想设置rsi一次,然后向后走计数次。

实际上,您也不希望/不需要多次读取count。

mov rbx, [rsi-1]              ; move the first rightmost number in rbx

由于rbx是8个字节长,因此它将读取[rsi-1]处的8个字节。正如我们所讨论的,这可能不是你想要的。

sub rbx, '0'                ; subtract hex value 30 for each character
; to get decimal value 0-9
mov rax, [rbx]              ; move the result in rax

你想把rbx复制成rax吗?因为这不是mov的作用。相反,它将尝试从rbx中的内容指定的内存位置进行读取。但是存储在rbx中的不是内存位置(应该是数字1,对吧?)。所以我预计这会因访问违规而崩溃。

如果你真的想把rbx复制到rax中,那就是mov rax, rbx

或者,为什么要将值读取到rbx中并复制它?为什么不首先使用rax呢?看看你的评论,你不打算用RBX做其他事情吗?

mul rdx                     ; multiply result, power of 10(rax*rdx)

好的,让我们来谈谈它的作用。简而言之,就是RDX:RAX=RAX*RDX。虽然您只指定RDX,但其余部分是隐含的。现在,"RDX:RAX"是什么意思?好吧,如果RAX和RDX中的值真的很大,那么将它们相乘会得到一个太大的结果,无法放入单个寄存器。因此mul使用2个寄存器来保存结果。RDX将是较高的比特,而RAX将保持较低的比特。

对于121,永远不会有足够大的结果来填充多个寄存器,所以RDX最终总是为零。这将是下面的一个问题。

add rbx, rax                ; stores the total in rbx

存储总数是一件好事,这正是你想要做的。但你已经在使用rbx做其他事情了。因此,当您第二次通过循环时,rbx将不会得到第一次循环的结果。

dec rsi                     ; decrement up until first character
cmp rsi, 0                  ; check if we are at the end of input/converted all input to decimal
je convertToHex             ; if so jump to conversion

让我们花点时间讨论一下cmp/je的作用。简而言之,cmp进行比较,然后设置一些其他指令(如je)可以使用的标志。然后je查看cmp设置的标志,并根据需要跳转。但事实证明,cmp并不是唯一设置标志的指令。dec也是如此。因此,您可以通过使用dec设置的标志来查看rsi是否为零,而无需执行额外的cmp。

(顺便说一句,如果你确实需要在没有做dec或其他事情的情况下检查零,test rsi,rsi的效率略高于cmp rsi,0)。

但这里更重要的问题是rsi不会为零。使用我在评论中给出的示例:

如果rsi为0x100,则"121"的3个字节将分别为0x100、0x101和0x102。

因此,如果我们从0x103开始(通常地址会大得多),那么我们对三个数字中的每一个都递减一次,我们不是在寻找零。那么,我们能减少什么,目前的值是3<咳嗽>rcx<咳嗽>

mov ax, [rdx]            ; move value of rdx to ax

还记得我说过把rdx设置为零会有问题吗?好吧,就是这样。如果rdx为零,那么您正在尝试读取内存位置[0]。这将是一个访问违规。由于rdx将在每个循环中为零,也许您应该选择一个不同的寄存器来存储您的功率。

imul ax, 10              ; updates to the next power by 10*1 (10^1, 10^2)

这种形式的刺激将有效地达到ax=ax*10。但是ax是你想要存储结果的地方吗?

jmp convertInputToDigits    ; if not, loop again

所以,这似乎有很多问题。是的,确实是这样。但你似乎正确地理解了你想做什么,即使你对如何做有点模糊。

希望这能帮助你更好地了解正在发生的事情,并为你指明正确的方向。

相关内容

  • 没有找到相关文章

最新更新