分配后的内存地址返回不同的值

时间:2019-04-08 18:18:09

标签: assembly x86 windows-7 nasm

我编写了以下程序以大写句子中每个单词的第一个字符:

extern _printf
extern _putchar

section .data
    char_form: db "%c", 10, 0
    int_form: db "%d", 10, 0
    str_form: db "%s", 10, 0
    str_low: db "ab c",10, 0        

section .text
    global  _main, _CapSentence

_main:
    mov ebp, esp; for correct debugging
    push    ebp
    mov     ebp, esp

    push   str_low
    call  _CapSentence
    add esp, 4

    push eax
    call _PrintString
    add esp,4

    mov     esp, ebp
    pop     ebp
    ret

_CapSentence:
    push    ebp      ; save the previous value of ebp for the benefi$
    mov     ebp, esp ; copy esp -> ebp so that ebp can be used as a $
    sub     esp, 4   ; create 1 local variables

    ;--------------------------;
    ; [ebp+8]== string-address ;
    ;--------------------------; 
    xor eax, eax 
    mov eax, [ebp+8]; obtain string address

    ;-------------------------;
    ; [ebp-4] == loop counter ;
    ;-------------------------;   
    mov [ebp-4], eax ; save address for loop counting

    while_cs:
        mov eax, [ebp-4];obtain current char address
        xor ecx, ecx
        mov cl, [eax];char ch = str[i];

        cmp ecx, '\0'; ch <?> '\0'
        je  while_exit_cs ; if(ch == '\0') break;

        cmp cl, 32; ch <?> wh-space
        jne test_i_equals_0 ;if(ch != wh-space)

    if_white_space:
        mov eax, [ebp-4]; obtain current char address
        xor ecx, ecx
        mov cl, [eax + 1]; char next = newString[i + 1];;        

        cmp ecx, '\0'
        je  test_i_equals_0 ; if(if (next == '\0'))
        ; else {
        mov eax, [ebp-4]; obtain current address
        xor ecx, ecx
        mov cl, [eax+1];obtain next character  

        push ecx
        call _ToUpper
        add esp, 4

        mov ecx, [ebp-4]
        mov [ecx+1], al; newString[i + 1] = ToUpper(next);          

    test_i_equals_0:
        mov eax, [ebp-4]
        mov ecx, [ebp+8]
        cmp eax, ecx ; i <?> 0
        jne increment_i ; if(i != 0)
        ;else
        ;{
        ; obtain curect address
        mov eax, [ebp-4]
        xor ecx, ecx
        mov cl, [eax] ; obtain current character

        ; convert to uppercase
        push ecx
        call _ToUpper ; 
        add esp, 4;        
        mov ecx, [ebp-4];
        mov byte [ecx], al; <=================================(1)
        xor eax, eax
        mov eax, [ecx]; <=====================================(2)

    increment_i:
        mov eax, [ebp-4]
        inc eax
        mov [ebp-4], eax
        mov eax, [ebp-4]; make sure char was assinged properly      

        jmp     while_cs   ; iterate through while 
    while_exit_cs:                

    mov eax, [ebp-4]; return str address

    add     esp, 4  ; destroy local variable
    mov     esp, ebp ; restore esp with ebp
    pop     ebp ; remove ebp from stack
    ret ; return the value of temporary variable 

_PrintString:
    push    ebp
    mov     ebp, esp

    mov     eax, [ebp+8]

    push    eax
    push    str_form
    call    _printf
    add     esp, 8 

    mov     esp, ebp
    pop     ebp
    ret


_ToUpper:
    push    ebp
    mov     ebp, esp

    xor     eax, eax
    mov     al, [ebp+8]; obtain argument character

    cmp     al, 'a'
    jb      return_failure_tu

    cmp     al, 'z'
    ja      return_failure_tu

    sub     al, 32

return_failure_tu:        
    mov     esp, ebp
    pop     ebp
    ret

查看标记的线。
在(1),我正在为地址分配一个值。
在(2),我得到了不同的值。

而且,循环永远不会结束。

这是怎么回事?


这是算法:

#include <stdio.h>
#include <malloc.h>
#include <string.h>

char ToUpper(char ch)
{
    if (ch >= 97)
    {
        if (ch <= 122)
        {
            return ch - 32;
        }
    }

    return ch;
}

char * CapSentence(char * string)
{
    int length = strlen(string);
    char * newString = (char *)malloc(sizeof(char)*(length + 2));
    strcpy_s(newString, length + 1, string);

    int i = 0;
    while (1)
    {
        char ch = newString[i];

        if (ch == '\0') break;

        if (ch != 32)//space
        {
        }
        else
        {
            char next = newString[i + 1];

            if (next != '\0')
            {
                newString[i + 1] = ToUpper(next);
            }
        }

        if (i == 0)
        {
            newString[i] = ToUpper(ch);
        }

        i++;
    }

    return newString;
}

int main(void)
{
    char * string = "ab c";

    printf("%s\n\n", string);

    string = CapSentence(string);

    printf("%s\n\n%d", string, strlen(string));

    return 0;
}

1 个答案:

答案 0 :(得分:1)

对于不同的值,如Raymond Chen回答,您将MOV一个字节,并比较它是否为4字节值。

虽然您的算法中的某些东西使我感到困扰,但这基本上是说“如果ch不是空白,则什么也不做。否则,对其进行处理”

        if (ch != 32)//space
    {
    }
    else
    {