1.任务描述:分别对如下两个数据交换程序进行反汇编,并对swap()函数的汇编语句进行注释,解释能或不能进行数据交换的原因。 //ex1.c #include <stdio.h> void Swap(int x,int y) { int temp; temp=x; x=y; y=temp; } int main() { int a,b; a=5; b=9; printf("a=%d,b=%d\n",a,b); Swap(a,b); printf("a=%d,b=%d\n",a,b); return 0; } //ex2.c #include <stdio.h> void Swap(int *x,int *y) { int temp; temp=*x; *x=*y; *y=temp; } int main() { int a,b; a=5; b=9 printf("a=%d,b=%d\n",a,b); Swap(&a,&b); printf("a=%d,b=%d\n",a,b); return 0; }
时间: 2024-03-10 15:49:35 浏览: 59
好的,我会分别对这两个程序进行反汇编,并对swap()函数的汇编语句进行注释。
首先是ex1.c的反汇编代码和注释:
```
; Function Swap
; Swap(int x,int y)
; {
; int temp;
; temp=x;
; x=y;
; y=temp;
; }
Swap:
push ebp ; 保存调用者的栈底指针
mov ebp, esp ; 设置本地栈
sub esp, 8 ; 为局部变量 temp 分配栈空间
mov DWORD PTR [ebp-8], DWORD PTR [ebp+8] ; temp=x;
mov DWORD PTR [ebp+8], DWORD PTR [ebp+12] ; x=y;
mov DWORD PTR [ebp+12], DWORD PTR [ebp-8] ; y=temp;
nop ; 空指令
leave ; 恢复调用者的栈底指针
ret ; 返回
; Function main
; int main()
; {
; int a,b;
; a=5;
; b=9;
; printf("a=%d,b=%d\n",a,b);
; Swap(a,b);
; printf("a=%d,b=%d\n",a,b);
; return 0;
; }
main:
push ebp
mov ebp, esp
and esp, -16 ; 为栈指针对齐
sub esp, 16 ; 为局部变量 a 和 b 分配栈空间
mov DWORD PTR [ebp-4], 5 ; a=5;
mov DWORD PTR [ebp-8], 9 ; b=9;
push DWORD PTR [ebp-8] ; printf 函数的第二个参数 b
push DWORD PTR [ebp-4] ; printf 函数的第一个参数 a
push OFFSET FLAT:.LC0 ; printf 函数的格式字符串 "a=%d,b=%d\n"
call printf ; 调用 printf 函数
add esp, 12 ; 恢复栈指针
mov eax, DWORD PTR [ebp-8] ; eax=b;
mov edx, DWORD PTR [ebp-4] ; edx=a;
push eax ; Swap 函数的第二个参数 y
push edx ; Swap 函数的第一个参数 x
call Swap ; 调用 Swap 函数
add esp, 8 ; 恢复栈指针
push DWORD PTR [ebp-8] ; printf 函数的第二个参数 b
push DWORD PTR [ebp-4] ; printf 函数的第一个参数 a
push OFFSET FLAT:.LC0 ; printf 函数的格式字符串 "a=%d,b=%d\n"
call printf ; 调用 printf 函数
add esp, 12 ; 恢复栈指针
mov eax, 0
leave
ret
```
在ex1.c中,swap()函数的参数是通过值传递的方式传递的,所以在函数内部对参数进行修改并不能改变函数外部的值。因此,这个函数并不能实现数据交换的功能。
接下来是ex2.c的反汇编代码和注释:
```
; Function Swap
; Swap(int *x,int *y)
; {
; int temp;
; temp=*x;
; *x=*y;
; *y=temp;
; }
Swap:
push ebp
mov ebp, esp
sub esp, 16
mov eax, DWORD PTR [ebp+12] ; eax=x;
mov edx, DWORD PTR [eax] ; edx=*x;
mov eax, DWORD PTR [ebp+8] ; eax=y;
mov ecx, DWORD PTR [eax] ; ecx=*y;
mov eax, DWORD PTR [ebp+12] ; eax=x;
mov DWORD PTR [eax], ecx ; *x=*y;
mov eax, DWORD PTR [ebp+8] ; eax=y;
mov DWORD PTR [eax], edx ; *y=*x;
nop
leave
ret
; Function main
; int main()
; {
; int a,b;
; a=5;
; b=9;
; printf("a=%d,b=%d\n",a,b);
; Swap(&a,&b);
; printf("a=%d,b=%d\n",a,b);
; return 0;
; }
main:
push ebp
mov ebp, esp
and esp, -16
sub esp, 16
mov DWORD PTR [ebp-4], 5
mov DWORD PTR [ebp-8], 9
push DWORD PTR [ebp-8] ; printf 函数的第二个参数 b
push DWORD PTR [ebp-4] ; printf 函数的第一个参数 a
push OFFSET FLAT:.LC0 ; printf 函数的格式字符串 "a=%d,b=%d\n"
call printf
add esp, 12
lea eax, [ebp-8] ; eax=&b;
push eax ; Swap 函数的第二个参数 y
lea eax, [ebp-4] ; eax=&a;
push eax ; Swap 函数的第一个参数 x
call Swap ; 调用 Swap 函数
add esp, 8
push DWORD PTR [ebp-8] ; printf 函数的第二个参数 b
push DWORD PTR [ebp-4] ; printf 函数的第一个参数 a
push OFFSET FLAT:.LC0 ; printf 函数的格式字符串 "a=%d,b=%d\n"
call printf
add esp, 12
mov eax, 0
leave
ret
```
在ex2.c中,swap()函数的参数是通过指针传递的方式传递的,所以在函数内部对参数进行修改可以改变函数外部的值。因此,这个函数可以实现数据交换的功能。在函数内部,使用了指针来访问参数对应的内存地址,并进行了数据交换,最终实现了数据交换的功能。
阅读全文