2016-06-26 12 views
1

私は、文字列から空白を削除し、スペースを含まない文字列を返すことになっているコードを書いています。コードは次の操作を行うことになっている:アセンブリdddデバッガ、(%ebx)として与えられたアドレスの下でメモリの内容を観察する方法

  • まずeaxebxに文字列の最初の文字のアドレスをコピーし、「アドレス」

  • という変数が、その後(%ebx)から1つの文字を取るをそして(%ebx)にスペースがある場合、それは宇宙

  • であるかどうかを確認し、私は次の文字を取得することにより、$1ebxを高める

  • (%ebx)に何か他のもの(ないスペース)だった場合は、その後eaxebxを高め、(%ebx) == 0場合は、次の文字

  • を処理し、その後、eaxにコピーし、その後、私は、文字列の最初のアドレスをコピー(中%eaxへの変数のアドレス)と

機能を終了し、私は(私はメモリウントにあるものを見るために%edx(%ebx)をコピーするレジスタで何が起こっているのか確認するためにdddを使用そのアドレスは(%ebx)で書かれており、私は処理しようとしている文字列の文字を表すことができる数字の代わりに非常に高い数字を取得します。 私のコードには構造的な問題があり、私は見ることができず、理解していないのではないかと心配しています。 コードは、最初に作成されたのとまったく同じ文字列を返します。スペースは削除されません。

変数 "zamiana"を無視すると、スペースの削除に関する問題を解決する際にコード内で使用されます。

#include <stdio.h> 
#include <stdlib.h> 

extern char * usun_spacje(char * wsk, int zamiana); 

int main() 
{ 
    char* wskaznik = malloc(100); 
    int zamiana = 0; 
    sprintf(wskaznik, "%s", "abc def gh ijk"); 
    printf("This is a processed text %s \n", usun_spacje(wskaznik, zamiana)); 
} 

アセンブリコード:いくつかの厳しい変更後

//usun_spacje(char * wsk, int zamiana); 
.data 
address: .long 0 
changes: .long 0 

# char -> 1 
# int -> 4 
# long -> 4 bytes 

.equ bufor,8 
.equ change,12 
#eax, ebx, ecx, edx 
#eax - beginning address of a string, this register will be used to write processed characters 
#ebx - beginning address of a string, this register will be used to read characters 
#general conception - take letter from ebx, process (remove spaces), save in eax 

.text 
.type usun_spacje, @function 
.global usun_spacje 

usun_spacje: 
     PUSHL %ebp 
     MOVL %esp, %ebp 
     MOVL bufor(%esp), %edx #temporarily use edx to store address of a string that we will process 
     MOVL %edx, address #remember the beginning address of a string that we are going to process, edx is free to use again 
     MOVL change(%esp), %ecx #remember the option whether I change to CAPS or not 
     MOVL %ecx, changes #ecx is free to use again 
     #PUSHL %ebx 
     MOVL address, %eax #to write processed characters 
     MOVL address, %ebx #to read characters 
loop: 
     MOVL (%ebx), %edx #for debugging purposes to see what is in memory under address given by ebx 
     CMP  $' ', (%ebx) #is space? 
     JE  delete_space #if a character under (%ebx) is space then remove it, if not, move from ebx into eax 
     MOVL (%ebx), %edx #take a character from (%ebx) and put temporarily into %edx 
     MOVL %edx, (%eax) #now move a character from %edx into (%eax), edx is free to be used again 
    #okay, so we moved a character from (%ebx) to (%eax), so we increase memory addresses to process the next char 
     ADDL $1, %eax #next memory address 
     ADDL $1, %ebx #nest memory address 
     CMP  $0, (%ebx) #is this the end of the string we process? 
     JE  end #if it is the end of the string, jump to end 
     JMP  loop #if not, continue 
end: 
     ADDL $0, (%eax) #add 0 at the end of the string 
     MOVL address, %eax #to return our new string, copy its beginning adress into eax 
     #POPL %ebx 
     MOVL %ebp, %esp #epilogue 
     POPL %ebp 
     RET 

delete_space: 
     ADDL $1, %ebx #increase the address in ebx 
     JMP loop #start analysis again 
+0

あなたは4バイトの代わりに、1 – Jester

+0

をロードし、私は(%のEBX)、SHR $ 8使ってみて、その後MOVB(%のEXB)、1バイトごとに取得するために%のDLしかし、それは動作しません。私もMOVB 1(%ebx)、%dlを試しましたが、正しく動作しません。 – Joanna

+0

ポインタを1だけ正しくインクリメントするので、 'movb(%ebx)、%dl'を使うだけです。 – Jester

答えて

0

、最終的にはコードが仕事を始めました。レジストリに関する洞察力のある発言をありがとう。

#include <stdio.h> 
#include <stdlib.h> 

extern char * usun_spacje(char * wsk, int zamiana); 

int main() 
{ 
    char* wskaznik = malloc(100); 
    int zamiana = 0; 
    sprintf(wskaznik, "%s", "A  b  c defg hi j"); 
    printf("This is a processed text %s \n", usun_spacje(wskaznik, zamiana)); 
} 

アセンブリコード:

//usun_spacje(char * wsk, int zamiana); 
.data 
address: .long 0 
changes: .long 0 

# char -> 1 
# int -> 4 
# long -> 4 bytes 

.equ bufor,8 
.equ change,12 
#eax, ebx, ecx, edx 
#eax - beginning address of a string, this register will be used to write processed characters 
#ebx - beginning address of a string, this register will be used to read characters 
#general conception - take letter from ebx, process (remove spaces), save in eax 

.text 
.type usun_spacje, @function 
.global usun_spacje 

usun_spacje: 
    PUSHL %ebp 
    MOVL %esp, %ebp 
    MOVL bufor(%esp), %edx #temporarily use edx to store address of a string that we will process 
    MOVL %edx, address #remember the beginning address of a string that we are going to process, edx is free to use again 
    MOVL change(%esp), %ecx #remember the option whether I change to CAPS or not 
    MOVL %ecx, changes #ecx is free to use again 
    PUSHL %ebx 
    MOVL address, %eax #to write processed characters 
    MOVL address, %ebx #to read characters 

loop: 
    MOVB (%ebx), %dl 
    CMPB $0, %dl #is this the end of the string we process? 
    JE  end #if it is the end of the string, jump to end 
    CMPB $' ', %dl #is space? 
    JE  delete_space #if a character under (%ebx) is space then remove it, if not, move from ebx into eax 
#module to change letters into CAPS 
    CMP  $0, %ecx 
    JE  continue 
    CMPB  $'a', %dl 
    JAE  change_letters 
continue: 
#move processed letter into destination string (the same string actually) 
    MOVB %dl, (%eax) #save a character in the resulting string 
    ADD  $1, %eax #next memory address OR INC 
    ADD  $1, %ebx #next memory address OR INC 
    JMP  loop #if not, continue 
end: 
    MOVB $0, %dl 
    MOVB %dl, (%eax) 
    MOVL address, %eax #to return our new string, copy its beginning adress into eax 
    POPL %ebx 
    MOVL %ebp, %esp #epilogue 
    POPL %ebp 
    RET 

#additional lines 
delete_space: 
    INC %ebx #increase the address in ebx 
    JMP loop #start analysis again 

change_letters: 
    ADD $-32, %dl 
    JMP continue 
関連する問題