Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 反转和更改给定字符串x86程序集的大小写_String_Assembly_Input_X86_Irvine32 - Fatal编程技术网

String 反转和更改给定字符串x86程序集的大小写

String 反转和更改给定字符串x86程序集的大小写,string,assembly,input,x86,irvine32,String,Assembly,Input,X86,Irvine32,该程序的目标是在切换每个字母的大小写时反转给定的字符串。字符串不能超过20个字符,若输入长度超过20个字符,程序要求用户再次输入字符串。当用户输入“回车”时,程序结束,打印结束句后程序结束 实施这一点,我有三个问题: 我尝试使用call ReadString获取输入字符串,由于此过程在给定enter键时停止,因此当我按enter键正常完成程序时,控制台冻结结束。如何更正代码,使其打印结束消息,然后以返回值0正常结束程序 若输入字符串长度超过20个字符,则应要求用户再次输入字符串。所以我写了一封信

该程序的目标是在切换每个字母的大小写时反转给定的字符串。字符串不能超过20个字符,若输入长度超过20个字符,程序要求用户再次输入字符串。当用户输入“回车”时,程序结束,打印结束句后程序结束

实施这一点,我有三个问题:

  • 我尝试使用call ReadString获取输入字符串,由于此过程在给定enter键时停止,因此当我按enter键正常完成程序时,控制台冻结结束。如何更正代码,使其打印结束消息,然后以返回值0正常结束程序

  • 若输入字符串长度超过20个字符,则应要求用户再次输入字符串。所以我写了一封信。但是由于某种原因,mov字节数,eax;cmp字节数,20;似乎无法正确过滤案例。当执行行mov bytecount eax时,bytecount的值是正确的,但是当程序执行下一行cmp bytecount 20时,bytecount的值改变。我不知道我做错了什么

  • CaseChange程序在执行时冻结,所以我猜它是无限循环的,但我找不到什么条件是错误的

  • .data
    最大长度=20
    prompt3字节“程序结束”,0
    缓冲区字节最大长度DUP(0)
    字节数德沃德?
    .代码
    主进程
    调用Clrscr
    L1:mov edx,偏移缓冲器
    mov ecx,缓冲区大小
    调用PromptForInput;打印输入提示
    调用读取字符串
    mov字节数
    cmp字节数,20;***如果字符串中的字符数大于20,请再次获取输入
    ja L1;***
    呼叫反向限制
    呼叫案例变更***
    偏移缓冲区
    通话记录;打印结果
    回路L1
    移动edx,偏移提示3;***输入后如何打印prompt3?
    通话记录
    出口
    主端
    案件变更程序
    普沙德
    偏移缓冲区
    L1:
    mov dl,字节PTR[eax]
    测试dl,dl
    jz L3
    cmp dl,‘A’
    jl L3
    异或dl,32
    cmp-dl,'z'
    L2:
    埃克斯公司
    jmp-L1
    L3:
    波帕德
    ret
    案例变更ENDP
    
    (输入提示):猫和狗

    (输出提示):.SGOd-DNA-STAc

    (输入提示):对于给定的限制太长

    (输入提示):

    程序结束

    手册告诉我们ReadString:

    从标准输入中读取最多包含ECX非空字符的字符串,当用户按Enter键时停止。
    在字符输入后存储空字节,但尾随的回车符和换行符未放入缓冲区。
    ECX应始终小于缓冲区大小(决不等于缓冲区大小),因为空字节可能是存储的第(ECX+1)个字符

    接下来,很明显,您需要放大缓冲区:

    buffer BYTE MaxLength + 1 DUP (0)
    
    如果指定了
    ECX=MaxLength
    ,则无法获得长度超过MaxLength字符的输入,因此不需要测试这种情况。(*)

    如果用户在没有前置字符的情况下按enter键,则ReadString将返回
    EAX=0
    。测试并跳转到最后一条消息

    一个很大的错误是您编写了
    循环L1
    loop
    指令与
    ECX
    寄存器一起工作,以执行已知次数的迭代。你的程序需要在没有附加条件的情况下跳回顶端。使用
    jmp L1

    最好是把事情逻辑地放在一起。不要将
    call PromptForInput
    call ReadString
    及其参数混合使用。您能否确保PromptForInput不会更改
    EDX
    ECX

    L1: call    PromptForInput
    
        mov     edx, OFFSET buffer
        mov     ecx, MaxLength
        call    ReadString         ; -> EAX
        test    eax, eax
        jz      L2                 ; Exit
    
        call    ReverseString       ; Is this working fine?
        call    CaseChange
    
        mov     edx, OFFSET buffer
        call    WriteString         ; Printing the result
    
        jmp     L1
    
    L2:
        mov     edx, OFFSET prompt3
        call    WriteString         ; Final message
    
        exit
    

    • cmp dl,‘A’
      jl L3
      ChangeCase过程需要遍历整个字符串,但一旦发现一个小于65的字节,您就会离开。使用ASCII码[0255]时,请使用无符号条件

    • 异或dl,32 实际上,您不会在字符串内存中写入任何更改

    • cmp-dl,'z'
      你不能按照这个标准行事

    如果只需要保留一个寄存器,则不要使用
    pushad
    popad

    CaseChange PROC
        push    esi
        mov     esi, OFFSET buffer
    L1:
        lodsb
        test    al, al        ; End of string ?
        jz      L2
        or      al, 32        ; If "A".."Z" Then "a".."z"
        cmp     al, 'a'
        jb      L1
        cmp     al, 'z'
        ja      L1
        xor     byte ptr [esi-1], 32  ; Change case IN string memory
        jmp     L1
    L2:
        pop     esi
        ret
    CaseChange ENDP
    

    (*)如果要强制执行此“字符串不能超过20个字符”错误,请定义更大的缓冲区,并允许ReadString返回超过20个字符,以便您可以跳回程序:

    buffer BYTE 99 + 1 DUP (0)
    
    ...
    
    L1: call    PromptForInput
    
        mov     edx, OFFSET buffer
        mov     ecx, 99
        call    ReadString         ; -> EAX
        cmp     eax, 20
        ja      L1
        test    eax, eax
        jz      L2                 ; Exit
    

    最后一个建议是,通过独立测试,确保反向限制和案例变更正常:

        call    ReverseString
        ;;;call    CaseChange
        mov     edx, OFFSET buffer
        call    WriteString         ; Printing the result
    
    后来

        ;;;call    ReverseString
        call    CaseChange
        mov     edx, OFFSET buffer
        call    WriteString         ; Printing the result
    
    只有那时

        call    ReverseString
        call    CaseChange
        mov     edx, OFFSET buffer
        call    WriteString         ; Printing the result
    

    你的回答对我帮助很大。非常感谢您的详细和有益的解释
        call    ReverseString
        call    CaseChange
        mov     edx, OFFSET buffer
        call    WriteString         ; Printing the result