我试图了解如何在程序集中使用堆栈,在我的尝试中,我在SO中的一个问题中遇到了以下代码,即:
push ecx
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, result_len
int 0x80
mov eax, 4
mov ebx, 1
mov ecx, esp
add [ecx], DWORD 48
mov edx, 2
int 0x80
在这种情况下ecx,持有一个数字,作者正在显示数字(如果我错了,请纠正我!)首先将堆栈指针移动到ecx,然后通过向内存添加48将数字转换为ascii字符ecx指向的地址。 他能用“pop ecx”做同样的事情然后转换成ascii吗? 我不太明白为什么作者正在以这种方式进行。 任何帮助将不胜感激。
答案 0 :(得分:2)
他是否能够通过“pop ecx”做同样的事情 转换为ascii?
没有。 sys_write系统调用需要一个指向要打印的字符串的指针。通过将ecx
推入堆栈,您可以在esp
中创建指针(地址)。
答案 1 :(得分:0)
让我们逐行解释代码
push ecx #ADDS THE VALUE IN THE REGISTER ECX TO THE STACK (TO SAVE IT FOR LATER USE...)
mov eax, 4 #USE stdout AS OUR OUTPUT
mov ebx, 1 #USE stdout AS OUR OUTPUT
mov ecx, result #POINTER TO THE MEMORY ADDRESS OF THE CHARACTERS TO OUTPUT
mov edx, result_len #MAX NUMBER OF CHARACTERS TO SHOW
int 0x80 #EXECUTE THE INTERRUPTION 0X80
mov eax, 4 #USE stdout AS OUR OUTPUT
mov ebx, 1 #USE stdout AS OUR OUTPUT
mov ecx, esp #MOVE THE POINTER FROM THE STACK POINTER OT THE ECX REGISTER THAT LETS US ACCESS EXC IN THE STACK
add [ecx], DWORD 48 #ADDS TO THE VALUE INSIDE OF THE ECX REGISTER THE VALUE OF 48 AS A DWORD TO FIT THE EXTENDED SIZE
mov edx, 2 #MAX NUMBER OF CHARACTERS TO SHOW
int 0x80
我认为这样做的是它获取某个值的值并将其存储在堆栈中,然后它将一个字符串输出到stdout,然后它获取先前存储在堆栈中的值并将其添加到所有寄存器中最后输出它。
这也可能有所帮助:http://www.tutorialspoint.com/assembly_programming/assembly_system_calls.htm
答案 2 :(得分:0)
如果我们使用EAX,EBX,ECX或EDX作为括号内的地址注册表,则DS是默认段。但是如果我们使用ESP或EBP,则SS是默认段。
所以指令:“添加[ecx],DWORD 48”将dword值添加到DS:ECX所指向的地址。
但是我们可以在我们的指令中添加一个段覆盖前缀,以便用另一个覆盖默认段。示例:“添加SS:[ecx],DWORD 48”。