汇编代码 - 找不到错误

时间:2016-06-25 15:19:54

标签: assembly i386

我会感谢我在代码中发现错误。我本来应该写一个函数,它将一个地址带到缓冲区,字母l,数字n和增量变量,它只能取2个值:0和1。 如果增量变量为0,则该函数应该重复相同的字母n次。如果增量变量为1,则该函数应返回一串后续字母,例如" abcd ...." (后续的ascii字符)。 字母l确定我们从字符串开始的字母。

我尝试使用ddd,它告诉我问题在于线路         MOVL%ecx,(%edx) 我知道寄存器edx和ecx中存在错误的值。 不过,我无法理解错误以及如何纠正错误。我将非常感谢你的帮助。

#include <stdio.h>
#include <stdlib.h>
extern char * generate_str(char * s, int c, int n, int inc);

int main()
{
    char s[100] = "something";
    char c = 'a';
    int n = 5;
    int inc = 0;
    printf("String %s\n", generate_str(s, (int)c, n, inc));
}

汇编代码:

.data
character: .int 0

# char -> 1
# int -> 4
# arguments: char * s, int c, int n, int inc

.equ bufor,8
.equ c,12
.equ n,16
.equ inc,20
#eax, ebx, ecx, edx

.text
.type generate_str, @function
.global generate_str

generate_str:

    PUSHL %ebp            #prolog of the function
    MOVL %esp, %ebp
    MOVL inc(%esp), %eax  #copy variable inc into eax
    MOVL n(%esp), %ebx    #copy variable n into ebx
    PUSHL %ecx            #save contents of ecx
    MOVL c(%esp), %ecx    #copy variable c into ecx temporarily
    MOVL %ecx, character  #copy variable c into reserved memory called character
    POPL %ecx             #restore contents of c
    MOVL bufor(%esp), %edx #copy addres of a buffer into edx

    CMP $0, %eax # eax > 0 ?  #is inc variable 0 or 1
    JA one                    #if it is 1, go to line "one"
    MOVL %ebx, %ecx           %copy value of variable n into ecx, it tells how many letters should be placed in the buffer 
p:
    PUSHL %ecx                #save contents of ecx
    MOVL character, %ecx      #copy character into ecx
    MOVL %ecx, (%edx)         #copy character into the place in the memory which address is given in edx
    POPL %ecx                 #restore contents of ecx
    ADDL $4, %edx             #increase value of edx by 4, so we move forwards in the memory to save another letter there
    loop p                    #loop until ecx is 0
    jmp end                   #jump to the final part of the function

one:                          #if the value of inc is 1 then do another loop  
    PUSHL %ecx                #save ecx and use this register to copy character into the place in memory which address is in the edx registry
    MOVL character, %ecx
    MOVL %ecx, (%edx)
    POPL %ecx
    ADDL $1, character        #increase ascii character by 1
    ADDL $4, %edx             #move in memory by 4 bytes so we can save the next letter
    loop one                  #continue loop until ecx is zero
    jmp end

end:
    MOVL %edx, %eax          #copy address of the final string into eax
    movl %ebp,%esp           #restore registers
    popl %ebp
RET

1 个答案:

答案 0 :(得分:0)

感谢您的建议。 DDD完成了它的工作。这是更正后的代码。老实说,我仍然有一些问题,理解为什么我应该添加$ 1而不是4美元,当我增加地址时我应该插入下一个char(因为它被转换为int)但它的工作原理。

#include <stdio.h>
#include <stdlib.h>
extern char * generate_str(char * s, int c, int n, int inc);

int main()
{
    char s[100] = "cos tam";
    char c = 'a';
    int n = 5;
    int inc = 0;
    printf("String %s\n", (char*) generate_str(s, (int)c, n, inc));

}

汇编代码:

#dane
.data
character: .int 0

# char -> 1
# int -> 4
# arguments: char * s, int c, int n, int inc

.equ bufor,8
.equ c,12
.equ n,16
.equ inc,20
#eax, ebx, ecx, edx

.text
.type generate_str, @function
.global generate_str

generate_str:
    PUSHL %ebp
    MOVL %esp, %ebp
    MOVL inc(%esp), %eax 
    MOVL n(%esp), %ecx 
    MOVL c(%esp), %ebx
    MOVL bufor(%esp), %edx 
    PUSHL %ebx      

    CMP $0, %eax
    JA one
p:
    MOVL %ebx, (%edx)
    ADDL $1, %edx
    loop p
    ADDL $0, %edx
    jmp end

one:
    MOVL %ebx, (%edx)
    ADDL $1, %ebx
    ADDL $1, %edx
    loop one    
    ADDL $0, %edx
    jmp end

end:
    MOVL bufor(%esp), %edx
    MOVL %edx, %eax
    movl %ebp,%esp
    popl %ebx
    popl %ebp
    RET

使用变量的版本

#dane
.data
letter: .int 0

# char -> 1
# int -> 4
# arguments: char * s, int c, int n, int inc

.equ bufor,8
.equ c,12
.equ n,16
.equ inc,20
#eax, ebx, ecx, edx

.text
.type generate_str, @function
.global generate_str

generate_str:
     PUSHL %ebp
     MOVL %esp, %ebp
     MOVL inc(%esp), %eax 
     MOVL n(%esp), %ecx 
     MOVL c(%esp), letter
     MOVL bufor(%esp), %edx 
     PUSHL %ebx 

     CMP $0, %eax
     JA one
 p:
     MOVL letter, %edi
     MOVL %edi, (%edx)
     ADDL $1, %edx
     loop p
     jmp end

one:
     MOVL %ebx, (%edx)
     ADDL $1, %ebx
     ADDL $1, %edx
     loop one   
     ADDL $0, %edx
     jmp end

end:
      MOVL bufor(%esp), %edx
      MOVL %edx, %eax
      MOVL %ebp,%esp
      popl %ebx
      popl %ebp
      RET