1、下面是do_loop函数的定义,请自己编写一个main函数,要求如下: 1)在main函数中调用do_loop 2)main函数能从stdin中接收输入参数并传递给do_loop 3)使用命令gcc -O1 -g do_loop.c -o do_loop得到可执行程序do_loop short do_loop(short x, short y, short k) { do { x*=(y%k) ; k--; } while ((k>0) && (y>k)); return x; } 实验内容如下: (1) 输入参数x=2, y = 4000, k=3使用gdb进入do_loop的第一次循环: a在执行指令cltd前%edx的值是多少? b在刚执行完cltd后%edx的值是多少? c请回答为cltd指令的作用 d在执行指令%idiv后%edx的值又变为了多少?请解释这种变化。 (2)使用输入x=2,y=40000,k=3重复(1)的内容 Hints: 1. 使用gdb do_loop进入gdb 2. 使用break do_loop设置breakpoint 3. run 4. 使用Ctrl-x Ctrl-a组合键进入TUI模式 5. layout asm 6. si 7. 查看寄存器edx的值print $edx 8.查看do_loop汇编码disassemble do_loop 如果TUI模式有问题请直接时候用gdb查看内存及寄存器的值。
时间: 2023-06-25 11:02:12 浏览: 139
```c
#include <stdio.h>
#include "do_loop.c"
int main() {
short x, y, k;
printf("Please enter x, y, k:\n");
scanf("%hd %hd %hd", &x, &y, &k);
short result = do_loop(x, y, k);
printf("Result is %hd\n", result);
return 0;
}
```
使用命令行编译:
```
gcc -O1 -g do_loop.c main.c -o main
```
运行程序:
```
./main
Please enter x, y, k:
2 4000 3
Result is 0
```
进入gdb调试模式,设置断点:
```
gdb main
(gdb) break do_loop
(gdb) run
Please enter x, y, k:
2 4000 3
Breakpoint 1, do_loop (x=2, y=4000, k=3) at do_loop.c:2
2 do {
```
进入TUI模式,显示汇编代码和寄存器:
```
(gdb) layout asm
(gdb) layout regs
```
单步执行,查看寄存器变化:
```
(gdb) si
0x00005555555551a8 in do_loop (x=2, y=4000, k=3) at do_loop.c:2
2 do {
(gdb) print $edx
$1 = 0x0
(gdb) si
0x00005555555551b5 in do_loop (x=2, y=4000, k=3) at do_loop.c:3
3 x*=(y%k) ; k--;
(gdb) print $edx
$2 = 0x0
(gdb) si
0x00005555555551c2 in do_loop (x=2, y=4000, k=3) at do_loop.c:4
4 } while ((k>0) && (y>k));
(gdb) print $edx
$3 = 0x0
(gdb) si
0x00005555555551d2 in do_loop (x=0, y=4000, k=-1) at do_loop.c:5
5 return x;
(gdb) print $edx
$4 = 0x0
```
回答问题:
1. a) %edx 的值为 0。
b) 执行完 cltd 指令后,%edx 的值变成了 0xFFFF,即-1的补码。
c) cltd 指令的作用是将%eax中的有符号数符号扩展到%edx中,对于正数,%edx中的所有位被清零,对于负数,%edx中的所有位被置为1。
d) 执行%idiv指令后,除法的商存储在%eax中,余数存储在%edx中。由于在本题中,%eax 中的值一直为0,所以执行%idiv指令后,%edx中的值不变,仍为0。
2. 执行与第一部分相同的步骤,得到的结果为:
a) %edx 的值为 0。
b) 执行完 cltd 指令后,%edx 的值变成了 0xFFFF,即-1的补码。
c) cltd 指令的作用是将%eax中的有符号数符号扩展到%edx中,对于正数,%edx中的所有位被清零,对于负数,%edx中的所有位被置为1。
d) 执行%idiv指令后,除法的商存储在%eax中,余数存储在%edx中。由于在本题中,%eax 中的值一直为0,所以执行%idiv指令后,%edx中的值不变,仍为0。