转换字符串中MASM到整数:ESI困难 [英] Converting string to integer in MASM: esi difficulty
问题描述
我写汇编语言(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已被更新
-
开始在字符串的开头
-
乘以10回答的值。
-
拆分每个字符掉字符串,并以48D减去获得的整数。防爆。学生进入156. 49存储在变量temp中的第一个字符。从49减48的整数是1。
-
添加整数答案的价值。
-
公司ESI(移动一个字符右)。
-
循环。
由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
Start at the beginning of the string
Multiply the value of answer by 10.
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.
Add integer to value of answer.
Inc esi (move one character right).
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 thetryAgain
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]
domovzx eax, [esi]
ormov al, [esi]
这篇关于转换字符串中MASM到整数:ESI困难的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!