首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在MASM中将字符串转换为整数: esi困难

在MASM中将字符串转换为整数: esi困难
EN

Stack Overflow用户
提问于 2012-12-01 23:22:18
回答 2查看 8K关注 0票数 3

我用汇编语言(MASM)编写了一个程序,允许学生练习计算组合。程序随机分配n和r,计算组合,然后提示学生提供答案。问题解决了*程序在很大程度上运行良好,但我遇到了一些挑战,将学生提供的整数字符串转换为整数,然后再将其与程序计算的结果进行比较。我以前没有问题地使用esi,但是无论出于什么原因,当程序到了计算esi内容(或字符串地址)并将其转换为整数的地步时,调试器就会显示esi的内容不是string.*中的第一个字符,只是为了清楚起见,我熟悉ReadInt,但我正试图弄清楚如何解析整数而不使用ReadInt。

更新:程序现在运行良好,只要用户输入有效的数字。我已经解决了esi没有指向正确位置的问题。我还添加了一些错误检查,以确保输入的值实际上是数字。但是,最初的错误检查意味着,当在下一次迭代中输入有效数字时,程序会在输入无效的输入后,继续返回消息“无效输入”。将tryAgain标记放在代码的第一行会导致程序继续返回无效的输入消息,即使有效输入跟随无效的输入。首先,我试图将tryAgain标记放在当前位置,但我认为它是在无限循环上运行的。第二,如果程序跳转到invalidInput,我会尝试重置变量,但这还没有修复(我在tryAgain的原始位置和当前位置尝试了这一点)。

编辑:只是为了澄清,这是为x86处理器。

下面是代码:

代码语言:javascript
复制
.data
result  DWORD   ?
temp        BYTE        21 DUP(0)
answer  DWORD   ?

.code
main    PROC

(一些初步程序要求)

代码语言:javascript
复制
push OFFSET temp        ;ebp+16
push OFFSET answer      ;ebp+12
push answerSize     ;ebp+8
call    getData

(更多的过程调用)

代码语言:javascript
复制
exit        ; exit to operating system
main ENDP

编辑代码:

代码语言:javascript
复制
;*************************************************
; prompts / gets the user’s answer.
; receives: the OFFSET of answer and temp and value of answerSize
; returns: none
; preconditions: none
; registers changed:  eax, ebx, ecx, edx, ebp, esi, esp
;*************************************************
getData PROC
push        ebp
mov     ebp,esp

tryAgain:
mWriteStr   prompt_1
mov     edx, [ebp+16]       ;move OFFSET of temp to receive string of integers
mov     ecx, 12
call        ReadString
cmp     eax, 10
jg      invalidInput

mov     ecx, eax        ;loop for each char in string
mov     esi,[ebp+16]    ;point at char in string

pushad
loopString:             ;loop looks at each char in string
    mov     ebx,[ebp+12]
    mov     eax,[ebx]   ;move address of answer into eax
    mov     ebx,10d     
    mul     ebx         ;multiply answer by 10
    mov     ebx,[ebp+12]    ;move address of answer into ebx
    mov     [ebx],eax       ;add product to answer
    mov     al,[esi]        ;move value of char into al register
    inc     esi         ;point to next char
    sub     al,48d      ;subtract 48 from ASCII value of char to get integer  

    cmp     al,0            ;error checking to ensure values are digits 0-9
    jl      invalidInput
    cmp     al,9
    jg      invalidInput

    mov     ebx,[ebp+12]    ;move address of answer into ebx
    add     [ebx],al        ;add int to value in answer

    loop        loopString  
popad
jmp     moveOn
invalidInput:               ;reset registers and variables to 0
    mov     al,0
    mov     eax,0
    mov     ebx,[ebp+12]
    mov     [ebx],eax
    mov     ebx,[ebp+16]
    mov     [ebx],eax       
    mWriteStr   error
    jmp     tryAgain
moveOn:
    pop     ebp
    ret     12
getData ENDP

为了让你知道我要做什么,这是我的伪代码:

伪码已被更新

  1. 从字符串的开头开始
  2. 把答案的值乘以10。
  3. 将每个字符除以字符串,再减去48d,得到整数。例如。学生进入156。49作为变量温度中的第一个字符存储。从49减去48。整数是1。
  4. 将整数添加到答案的值中。
  5. Inc esi (向右移动一个字符)。
  6. 循环播放。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-01 23:30:00

将每个字符从字符串中拆分,再除以48d。

你想减法而不是除法。

关于esi问题,请说明如何调用此函数。也许[ebp+16]不是缓冲区的偏移量,或者存在缓冲区溢出。您还可以使用调试器设置内存、写入、监视该地址并查看是谁更改了该地址。

而且,您的invalidInput标签不在代码中,但我怀疑tryAgain标签位于错误的位置。在开场白之后你可能想要它。

顺便说一句,进行这种转换的典型方法是从字符串开始向前,并在每一步中将部分结果乘以10。这样您就不需要PowerTen函数了。

Update:您正在加载4个字节,因此一次从您的字符串中加载4个字符,这就是您看到意外值的原因。代替mov eax,[esi],做movzx eax, [esi]mov al, [esi]

票数 1
EN

Stack Overflow用户

发布于 2012-12-02 01:02:21

若要在[esi]中从当前字符串索引指针中移动字节,需要使用以下操作之一:

代码语言:javascript
复制
movzx   eax, byte ptr[esi]
; or
mov     al, byte ptr[esi]

BYTE PTR告诉MASM,您希望在esi中的地址上处理一个字节。

我不确定你想这样做:

代码语言:javascript
复制
tryAgain:
    push    ebp
    mov     ebp, esp
    mWriteStr   prompt_1 

因为每次用户输入一个错误的提示,然后跳转到tryAgain,您就会继续“设置堆栈”。也许这是:

代码语言:javascript
复制
    push    ebp
    mov     ebp, esp

tryAgain:
    mWriteStr   prompt_1 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13664778

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档