转换字符串中MASM到整数:ESI困难 [英] Converting string to integer in MASM: esi difficulty

查看:234
本文介绍了转换字符串中MASM到整数:ESI困难的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写汇编语言(MASM)的程序,让学生练习计算的组合。该方案随机分配n和r,计算组合,然后提示学生提供答案。 问题解决了*的对于大部分的程序运作良好,但我遇到了一些挑战由学生提供的整数字符串转换成一个整数,然后可以通过程序计算出的结果进行比较。我用ESI之前没有问题,但是由于各种原因,当程序到达哪里ESI的内容(或字符串的地址)将被评估,并转换为整数的点,调试器显示该内容ESI是​​不是字符串中的第一个字符。的* 只是要清楚,我熟悉的readInt,但我试图找出如何解析的整数,而无需使用的readInt。

更新:程序现在工作得很好,只要用户输入有效的数字。我已经解决了问题,与ESI在正确的位置不指向。我也把一些错误检查,以确保输入的值实际上是数字。然而,最初的错误检查意味着,之后才下一次迭代过程中有效的数字输入的输入无效,程序不停地返回消息无效输入。把TRYAGAIN标签在code的第一行会导致程序来保持,即使有效输入如下无效的输入返回无效的输入信息。首先,我试图把TRYAGAIN标签在其当前职位,但我认为这是对一个无限循环运行。其次,我试图如果程序跳转到invalidInput重置变量,但是这并没有固定它(我在原来的位置和当前位置与TRYAGAIN尝试这样做)。

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

这里的code:

 。数据
导致DWORD?
临时BYTE 21 DUP(0)
回答DWORD?。code
主要PROC

(有些preliminary过程调用)

 推OFFSET温度; EBP + 16
推OFFSET的答案; EBP + 12
推answerSize; EBP + 8
打电话的getData

(更多过程调用)

 退出;退出到操作系统
主要ENDP

EDITED code:

 ; ********* ************
;提示/获取用户的答案。
;接收:偏移答案,温度和answerSize的价值
;返回:无
; preconditions:无
;改变寄存器:EAX,EBX,ECX,EDX,EBP,ESI,ESP
; *******************
PROC的getData
推EBP
MOV EBP,ESP再试一次:
mWriteStr prompt_1
MOV EDX,[EBP + 16];将OFFSET温度的接收整数串
MOV ECX,12
调用ReadString
CMP EAX,10
JG invalidInputMOV ECX,EAX;循环为字符串中的每个字符
MOV ESI,[EBP + 16]点在串字符PUSHAD
loopString:;环着眼于字符串中的每个字符
    MOV EBX,[EBP + 12]
    MOV EAX,[EBX];将答案地址到EAX
    MOV EBX,10D
    MUL EBX;乘以10回答
    MOV EBX,[EBP + 12];答案的举动地址到EBX
    MOV [EBX],EAX;增加产品的答案
    MOV人,[ESI];焦炭移动值到人寄存器
    INC ESI;指向下一个字符
    子人,48D;从CHAR得到整数ASCII值减去48    CMP人,0;错误检查,以确保值是数字(0-9)
    JL invalidInput
    CMP人,9
    JG invalidInput    MOV EBX,[EBP + 12];答案的举动地址到EBX
    添加[EBX]人;在回答加INT价值    环loopString
POPAD
JMP这个MoveOn
invalidInput:;复位寄存器和变量为0
    MOV人,0
    MOV EAX,0
    MOV EBX,[EBP + 12]
    MOV [EBX],EAX
    MOV EBX,[EBP + 16]
    MOV [EBX],EAX
    mWriteStr错误
    JMP TRYAGAIN
继续:
    流行EBP
    RET 12
ENDP的getData

只要你有我这个要去的地方的感觉,这是我的伪code:

伪code已被更新


  1. 开始在字符串的开头


  2. 乘以10回答的值。


  3. 拆分每个字符掉字符串,并以48D减去获得的整数。防爆。学生进入156. 49存储在变量temp中的第一个字符。从49减48的整数是1。


  4. 添加整数答案的价值。


  5. 公司ESI(移动一个字符右)。


  6. 循环。



解决方案

  

由48D拆分每个字符断弦和鸿沟。


您想减,而不是分裂。

至于 ESI 问题,请给这个函数是如何被调用。也许 [EBP + 16] 不偏移的缓冲区,或者有一个缓冲区溢出。您还可以使用调试器来设置该地址存储器写手表,看看谁更改它。

另外,你的 invalidInput 标签是不是在code,但我怀疑 TRYAGAIN 标签在错误的地方。你可能希望它的序幕之后。

顺便说一下,要做到这一点的转换典型方法是从字符串转发的开始去,并保持在每个步骤中的部分结果乘以10。这样,你不需要 PowerTen 功能。

更新:您加载4个字节,因此4个字符从字符串一次,这就是为什么你看到意想不到的价值。相反 MOV EAX,[ESI] 不要 MOVZX EAX,[ESI] MOV人的[ESI]

I've written a program in assembly language (MASM) to allow students to practice calculating combinations. The program randomly assigns n and r, calculates the combination, then prompts the student to provide the answer. Problem solved *For the most part the program is working well, but I'm running into some challenges converting the integer string provided by the student into an integer that can then be compared with the result calculated by the program. I've used esi before without problem, but for whatever reason, when the program gets to the point where the contents of esi (or the address of the string) are to be evaluated and converted to an integer, debugger is showing that the contents of esi are not the first char in the string.* Just to be clear, I am familiar with ReadInt, but am trying to figure out how to parse integers without using ReadInt.

UPDATE: The program now works well as long as the user inputs valid numbers. I've solved the issues with esi not pointing in the right spot. I've also put in some error checking to ensure that the values entered are actually numbers. However, initially the error checking meant that following an invalid input when valid numbers are entered during the next iteration, the program kept returning the message "invalid input". Putting the tryAgain tag in the first line of code causes the program to keep returning the invalid input message even when valid input follows invalid input. First, I attempted to put the tryAgain tag in its current position, but I think it's running on an infinite loop. Second, I attempted to reset variables if the program jumps to invalidInput, but that hasn't fixed it (I tried this with tryAgain in its original position and current position).

EDIT: Just to clarify, this is for x86 processors.

Here's the code:

.data
result  DWORD   ?
temp        BYTE        21 DUP(0)
answer  DWORD   ?

.code
main    PROC

(some preliminary procedure calls)

push OFFSET temp        ;ebp+16
push OFFSET answer      ;ebp+12
push answerSize     ;ebp+8
call    getData

(more procedure calls)

exit        ; exit to operating system
main ENDP

EDITED CODE:

;*************************************************
; 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

Just so you have a sense of where I'm going with this, here's my pseudocode:

Pseudocode has been updated

  1. Start at the beginning of the string

  2. Multiply the value of answer by 10.

  3. Split each character off the string and subtract by 48d to get the integer. Ex. student enters 156. 49 is stored as the first char in the variable temp. Subtract 48 from 49. The integer is 1.

  4. Add integer to value of answer.

  5. Inc esi (move one character right).

  6. Loop.

解决方案

Split each character off the string and divide by 48d.

You want to subtract, not divide.

As to the esi problem, please show how this function is called. Maybe [ebp+16] isn't the offset of the buffer, or there is a buffer overflow. You can also use your debugger to set a memory write watch on that address and see who changes it.

Also, your invalidInput label is not in the code, but I suspect the tryAgain label is in the wrong place. You probably want it after the prologue.

By the way, the typical method to do this conversion is to go from the start of the string forwards, and keep multiplying the partial result by 10 in each step. That way you don't need the PowerTen function.

Update: you are loading 4 bytes, hence 4 characters from your string at once, that's why you see the unexpected value. Instead of mov eax,[esi] do movzx eax, [esi] or mov al, [esi]

这篇关于转换字符串中MASM到整数:ESI困难的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆