assembly 使用fasm编写一个x86汇编程序,将用户输入的整数(从-100到100)转换为文本

i2byvkas  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(102)

使用fasm编写一个x86汇编程序,将用户输入的整数(从-100到100)转换为文本。
下面是我推荐的一个算法:
1.要求用户输入数字并存储到[Num]中
1.如果number小于0,输出“negative”并将其更改为正数
1.打印所有异常-检查编号是否为100、0、10、11、12、13、14、15、16、17、18、19。如果是,输出数字并结束
1.将数字除以10,并将答案存储为[商]和[余数]
1.将Quotient与20,30,40,50,60,70,80,90进行比较,并输出十位数-例如“二十”
1.将余数与1、2、3、4、5、6、7、8、9进行比较,并输出一位数-例如“五”
1.跳转到开始重复整个程序
示例输出此x86汇编程序将整数转换为文本。
输入一个介于-100到100之间的整数:73
七十三
输入一个介于-100到100之间的整数:-100
负一百
有人能帮我这个程序吗
我的意思是我写了程序,但完全不能得到预期的输出

format PE console
entry start

include 'win32ax.inc'

section '.data' data readable writable
    Num dd ?
    negative db "negative ", 0
    exceptions db "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", 0
    tens db "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety", 0
    output_msg db "%s", 0
    intro_msg db "This x86 assembly program converts an integer to text.", 0
    input_msg db "Enter an integer from -100 to 100: ", 0

section '.code' code readable executable
start:
    cinvoke printf, intro_msg
    cinvoke printf, input_msg
    cinvoke scanf, "%d", Num     ; Read user input
    
    mov eax, [Num]
    cmp eax, 0
    jge check_exceptions
    
    ; Output "negative " and change to positive
    cinvoke printf, negative
    neg eax
    mov [Num], eax

check_exceptions:
    cmp eax, 100
    je output_result
    
    cmp eax, 0
    je output_exception
    
    cmp eax, 10
    jl divide_by_10
    
    cmp eax, 20
    jl output_tens
    
    mov edx, eax
    shr eax, 1
    shl edx, 31
    sar eax, 31
    xor edx, eax
    sub edx, eax
    movzx eax, dx
    
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

divide_by_10:
    ; Divide by 10 to get tens and ones digits
    mov ebx, 10
    xor edx, edx
    div ebx
    movzx ecx, dl    ; Remainder is ones digit
    movzx ebx, al    ; Quotient is tens digit
    
    cmp ebx, 0
    je output_ones
    
    ; Output tens digit if not zero
    lea edx, [tens + ebx * 4]
    cinvoke printf, output_msg, edx
    
output_ones:
    cmp ecx, 0
    je restart
    
    ; Output ones digit
    lea edx, [exceptions + ecx * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

output_tens:
    sub eax, 10
    lea edx, [tens + eax * 4]
    cinvoke printf, output_msg, edx
    
    jmp restart

output_exception:
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx

output_result:
    ; Output the number as text
    lea edx, [exceptions + eax * 4]
    cinvoke printf, output_msg, edx

restart:
    jmp start

section '.idata' import data readable
    library msvcrt, 'msvcrt.dll'
    import msvcrt, printf, 'printf', scanf, 'scanf', ExitProcess, 'ExitProcess'

so after this when i run the program and give the input as 5 the output is something else. please if anyone could help me fix this issue.i would really appreciate it.
e4eetjau

e4eetjau1#

我的意思是我写了程序但完全不能得到预期的输出
这是我非常怀疑的事情!你在用人工智能吗?
考虑以下几点:

mov edx, eax
shr eax, 1
shl edx, 31
sar eax, 31
xor edx, eax
sub edx, eax
movzx eax, dx
    
lea edx, [exceptions + eax * 4]

这个蹩脚的代码在这里做什么?为什么您希望通过简单的4进制扩展来访问不同长度的字符串(有些超过4个字符)?

cmp eax, 10
jl divide_by_10

又是一个毫无意义的例子。为什么一个理智的人想要除以10,如果(正)数已经小于10?
下面是我推荐的一个算法:
请不要遵循这个建议。使用下一个想法:
1.处理消极的输入,就像你已经在做的那样。
1.创建一个包含所有您需要的唯一单词的列表(总共不超过24个)。最长的单词是“七十”。因为它有7个字符,所以我建议您将每个单词存储在8字节的记录中。此固定大小将允许使用缩放寻址模式[List+EAX*8]
1.创建一个包含101个字大小的值的表,其低字节引用任何字符串,其高字节可选地引用另一个字符串。当然匹配剩余的输入数字[0,100]。
1.使用您输入的数字作为表中的索引。
1.使用表中的单词从内存中取出一个或两个字符串并打印它们。
结果:数据多了一些,但代码少了很多(意大利面条)。

相关问题