【问题标题】:Implementing a toupper function in x86 assembly在 x86 汇编中实现 toupper 函数
【发布时间】:2014-02-22 00:34:22
【问题描述】:

我在 VS 2012 中使用 x86 程序集,试图将一些旧代码转换为程序集。我遇到的问题是访问和更改数组值(这些值是字符),我不知道该怎么做。我已经包含了 cmets,所以你可以看到我的思考过程

    void toUpper(char *string) {
    __asm{

    PUSH EAX
    PUSH EBX
    PUSH ECX
    PUSH EDX
    PUSH ESI
    PUSH EDI

    MOV EBX, string
    MOV ECX, 0 // counter
    FOR_EXPR: // for loop
    CMP EBX, 0 //compare ebx to 0
    JLE END_FOR // if ebx == 0, jump to end_for
    CMP EBX, 97 // compare ebx to 97
    JL ELSE // if  ebx < 97, jump else
    CMP EBX, 122 // compare ebx to 122
    JG ELSE // if ebx > 122, jump else

    // subtract 32 from current array value
    // jump to next element

    JMP END_IF

    ELSE:
    // jump to next element

    END_IF:
    JMP FOR_EXPR

    END_FOR:


    POP EDI
    POP ESI
    POP EDX
    POP ECX
    POP EBX
    POP EAX

       }
    }

非常感谢任何帮助!

【问题讨论】:

    标签: arrays assembly x86 ascii


    【解决方案1】:

    在我看来,基本问题是您正在使用字符串的 地址 加载 EBX,然后尝试使用它,就好像它包含字符串内部的一个数据字节一样。

    我可能会做一些不同的事情。我可能会将字符串的地址加载到 ESI 中并使用它来间接读取字符串的内容。

        mov esi, string
    next_char:
        lodsb
        test al, al     ; check for end of string
        jz done      
        cmp al, 'a'     ; ignore unless in range
        bl next_char
        cmp al, 'z'
        bg next_char
        sub al, 'a'-'A' ; convert to upper case         
        mov [esi-1], al ; write back to string
        jmp next_char
    

    您可以为此使用 EBX 而不是 ESI,但 ESI 更惯用。您还可以使用一些技巧来对此进行一些优化,但在您了解基础知识之前,它们大多会增加混乱。使用现代处理器,它们可能不会有太大的不同——无论如何,这很可能与您的内存带宽一样快。

    【讨论】:

    • 嗯,好的,谢谢您的回复 :) 另外,如何取消引用程序集中的指针?
    • 代码显示了几种最常见的方式。 lodsbesi 指向的地址隐式加载al,然后递增esimov [esi-1], alal 移动到esi 中保存的地址(在本例中为减一)。
    猜你喜欢
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 2020-12-05
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多