在x86程序集中实现toupper功能

时间:2014-01-29 22:31:08

标签: arrays assembly x86 ascii

我正在玩VS 2012中的x86程序集,尝试将一些旧代码转换为程序集。我遇到的问题是访问和更改数组值(值是字符),我不知道如何去做。我已经包含了评论,因此您可以查看我的思考过程

    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

       }
    }

非常感谢任何帮助!

1 个答案:

答案 0 :(得分: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更加惯用。还有一些技巧可以用来优化这一点,但在了解基础知识之前,它们通常会增加混乱。使用现代处理器,无论如何它们可能不会产生太大的影响 - 无论如何,这可能会以带宽的速度运行到内存中。