【发布时间】:2016-06-25 15:19:53
【问题描述】:
如果能在我的代码中发现错误,我将不胜感激。我本来应该写一个函数,它接受一个缓冲区的地址、字母 l、数字 n 和只能接受 2 个值的增量变量:0 和 1。 如果增加变量为 0,则该函数应该重复同一个字母 n 次。如果增加变量为 1,则该函数应返回一串后续字母,例如“abcd....”(后续 ascii 字符)。 字母 l 决定了我们以字符串开头的字母。
我尝试使用 ddd,它告诉我问题出在线路上 移动 %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
【问题讨论】:
-
MOVL bufor(%esp), %edx也许你的意思是LEAL bufor(%esp), %edx。很难说,因为您没有正确注释您的代码。此外,由于您现在显然可以使用ddd,单步执行代码并查看它在哪里出错,不要只查看错误指令。 PS:ebx是被调用者保存的寄存器。 -
我在代码中添加了 cmets。 ddd中的一步如何?每次我按“步骤”时,它都会告诉我程序没有运行。每次我运行程序时,它都会在我按下“step”之前完成。
-
您在函数的开头或任何您想要的地方放置一个断点,然后您可以从那里单步执行。是的,
copy address你需要使用lea而不是mov。