2017-03-16 181 views
2

我是汇编新手,正在为我的实验室工作,为汇编类。在这部分实验中,我需要将字符串转换为相反的大写字母。因此,例如:更改字母大小写(汇编x86)

如果给定的字符串

TheDonald

它应该返回

tHEdONALD

可以有时间或其他特殊字符,在这种情况下,我会离开独自一人。我也不允许使用32位寄存器。我应该只使用8位版本的x86通用寄存器。

到目前为止,我有这样的:

void changeCase(char *string) 
{ 
    __asm 
    { 
    // BEGIN YOUR CODE HERE 

    mov eax, string; // move the string into eax 
    mov ecx, 0; // ecx will be counter 

    BEGIN_LOOP: 
    cmp byte ptr[eax + ecx * 1], 0; 
    je END; 

    mov al, byte ptr[eax + ecx * 1]; // get the value of the current counter 

    cmp al, 65; // compare first char with A 
    jl NEXT_INDEX; 

    cmp al, 91; 
    jl UPPER_CASE; 

    cmp al, 97; 
    jl NEXT_INDEX; 

    cmp al, 123; 
    jl LOWER_CASE; 

    jmp NEXT_INDEX; 

    UPPER_CASE: // if upper case, make it lower case then go to next index 
    add al, 32; 
    mov byte ptr[eax + ecx * 1], al; 
    jmp NEXT_INDEX; 
    LOWER_CASE: // if lower case, make it upper case then go to next index 
    sub al, 32; 
    mov byte ptr[eax + ecx * 1], al; 
    jmp NEXT_INDEX; 
    NEXT_INDEX: 
    inc ecx; 
    jmp BEGIN_LOOP; 
    END: 
    // END YOUR CODE HERE 
    } 
} 
+2

你不能指望人们编写代码或为你写一篇教程;这不是该网站的内容。开始,然后在有特定问题时回复。如果你不知道从哪里开始,你需要从老师那里得到帮助。 – Carcigenicate

+0

Woops,用我的代码再次编辑帖子 – dppham1

+1

回想一下,第5位(第6位)是7位ASCII中的**情况位**。你只需要改变这一点就可以影响案例。您可以使用'或'或'xor'来获得您的优势。 –

回答

5

在你的代码的问题是,你正在使用aleax两种不同的目的。
aleax的一部分。所以如果你改变了al你实际上改变了eax的最低有效字节。
由于您使用eax作为基址指针,因此您不应该操作它,而应使用免费寄存器(如edx及其最低字节dl)来执行大写操作。
如果你确实操纵了al那么指针eax将指向所有导致不需要结果的地方。

深入了解代码,不需要同时使用ecxeax作为指针,其中一个就足够了,因为通过读取字符串的终止零字节可以告诉您该字符串在末尾。

您可以轻松地优化这些代码就像这样:

__asm{ 
    // BEGIN YOUR CODE HERE 

    mov eax, string; // move the string into eax 

BEGIN_LOOP: 
    mov dl, byte ptr[eax]; //get the current char. 
    test dl,dl    //is it the terminating zero? 
    jz END     //yes, we're done 

    cmp dl, 'A'; // compare first char with A 
    jl NEXT_INDEX;   //smaller than A, skip 

    cmp dl, 'z'; //compare char with z 
    jg NEXT_INDEX;  //bigger than z, skip 

    xor dl,32    //'a' = 'A' + 32 and 'A' = 'a' - 32 use xor to filp that bit 
    cmp dl,'z'    //Make sure we don't flip '[]\^_' 
    cmovle [eax],dl  //only write when result within bounds 
NEXT_INDEX:    //write back the flipped char. 
    inc eax;    //next char. 
    jmp BEGIN_LOOP; 
END: 
} 

有很多方法来进一步优化,但我不想过于复杂的问题。
请注意,在x86_32编程中,大多数平台上的eax,ecxedx都被认为是易失性,某些其他寄存器可能不会。因此,只有使用这些寄存器才能避免使用这些寄存器会更好。
如果你使用其他的寄存器,你必须在push那么在例程开始和pop他们在例程退出之前。

+0

这段代码也会翻转'[\]^_ \'',所以需要再进行一次测试(在使用'cmp dl'之前写入'xor dl,32'之前,'z''会再次修复它)。我建议使用cmp dl,'A'和cmp dl,'z'来明确测试的内容。条件跳转是错误的,无论是'jb + ja'还是'jl + jg'都可以工作。 (你让我感到生锈,我没有注意到明显的'mov al,[eax ...]原始帖子问题:)) – Ped7g

相关问题