深入理解计算机系统 CSAPP 家庭作业4.47

void bubble_a(long* start, long *end) {
	long *i, *last;
	for (last = end; last > start; last--) {
		for (i = start; i < last; i++) {
			if (*(i+1) < *i) {
				long t = *(i+1);
				*(i+1) = *i;
				*i = t;
			}
		}
	}
}

gcc -S -Og bubble_a.c

linux 运行以上指令获得X86-64的汇编 仿照这个汇编弄出Y86-64的

	.file	"bubble_a.c"
	.text
	.globl	bubble_a
	.type	bubble_a, @function
bubble_a:
.LFB0:
	.cfi_startproc
	jmp	.L2
.L3:
	addq	$8, %rax
.L5:
	cmpq	%rsi, %rax
	jnb	.L7
	movq	8(%rax), %rdx
	movq	(%rax), %rcx
	cmpq	%rcx, %rdx
	jge	.L3
	movq	%rcx, 8(%rax)
	movq	%rdx, (%rax)
	jmp	.L3
.L7:
	subq	$8, %rsi
.L2:
	cmpq	%rdi, %rsi
	jbe	.L8
	movq	%rdi, %rax
	jmp	.L5
.L8:
	rep ret
	.cfi_endproc
.LFE0:
	.size	bubble_a, .-bubble_a
	.ident	"GCC: (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0"
	.section	.note.GNU-stack,"",@progbits
/* bubble_a.ys */
.pos 0
	irmovq stack, %rsp  	# Set up stack pointer
	call main		# Execute main program
	halt			# Terminate program 
 
# Array of 4 elements
.align 8
array:	
  .quad 0x0000000000000004
  .quad 0x0000000000000003
  .quad 0x0000000000000002
  .quad 0x0000000000000001
 
main:
 	irmovq array,%rdi
	irmovq $4,%rsi
	call bubble_a		# sum(array, 4)
	ret
 
 
# bubble_a(long * data,long count)
# array in %rdi, count in %rsi

bubble_a:
	jmp	L2
L3:
	irmovq 	$8,%r8
	addq	%r8, %rax
L5:
	rrmovq	%rsi, %r8
	rrmovq	%rax, %r9
	subq	%r8, %r9
	jge	L7
	mrmovq	8(%rax), %rdx
	mrmovq	(%rax), %rcx
	rrmovq	%rcx, %r8
	rrmovq	%rdx, %r9
	subq	%r8, %r9
	jge	L3
	rmmovq	%rcx, 8(%rax)
	rmmovq	%rdx, (%rax)
	jmp	L3
L7:
	irmovq 	$8,%r8
	subq	%r8,%rsi
L2:
	rrmovq	%rdi, %r8
	rrmovq	%rsi, %r9
	subq	%r8, %r9
	jle	L8
	rrmovq	%rdi, %rax
	jmp	L5
L8:
	ret

.pos 200
stack:

bubble_a.ys文件保存在一个Y86-64模拟器文件夹中 

Y86-64模拟器的安装攻略请自行百度,注意只支持ubuntu-18及以下的系统。

终端键入指令:

make bubble_a.yo

模拟器会根据bubble_a.ys生成bubble_a.yo文件 以此验证是否编译成功

                            | /* bubble_a.ys */
0x000:                      | .pos 0
0x000: 30f4c800000000000000 | 	irmovq stack, %rsp  	# Set up stack pointer
0x00a: 803800000000000000   | 	call main		# Execute main program
0x013: 00                   | 	halt			# Terminate program 
                            |  
                            | # Array of 4 elements
0x018:                      | .align 8
0x018:                      | array:	
0x018: 0400000000000000     |   .quad 0x0000000000000004
0x020: 0300000000000000     |   .quad 0x0000000000000003
0x028: 0200000000000000     |   .quad 0x0000000000000002
0x030: 0100000000000000     |   .quad 0x0000000000000001
                            |  
0x038:                      | main:
0x038: 30f71800000000000000 |  	irmovq array,%rdi
0x042: 30f60400000000000000 | 	irmovq $4,%rsi
0x04c: 805600000000000000   | 	call bubble_a		# sum(array, 4)
0x055: 90                   | 	ret
                            |  
                            |  
                            | # bubble_a(long * data,long count)
                            | # array in %rdi, count in %rsi
                            | 
0x056:                      | bubble_a:
0x056: 70c600000000000000   | 	jmp	L2
0x05f:                      | L3:
0x05f: 30f80800000000000000 | 	irmovq 	$8,%r8
0x069: 6080                 | 	addq	%r8, %rax
0x06b:                      | L5:
0x06b: 2068                 | 	rrmovq	%rsi, %r8
0x06d: 2009                 | 	rrmovq	%rax, %r9
0x06f: 6189                 | 	subq	%r8, %r9
0x071: 75ba00000000000000   | 	jge	L7
0x07a: 50200800000000000000 | 	mrmovq	8(%rax), %rdx
0x084: 50100000000000000000 | 	mrmovq	(%rax), %rcx
0x08e: 2018                 | 	rrmovq	%rcx, %r8
0x090: 2029                 | 	rrmovq	%rdx, %r9
0x092: 6189                 | 	subq	%r8, %r9
0x094: 755f00000000000000   | 	jge	L3
0x09d: 40100800000000000000 | 	rmmovq	%rcx, 8(%rax)
0x0a7: 40200000000000000000 | 	rmmovq	%rdx, (%rax)
0x0b1: 705f00000000000000   | 	jmp	L3
0x0ba:                      | L7:
0x0ba: 30f80800000000000000 | 	irmovq 	$8,%r8
0x0c4: 6186                 | 	subq	%r8,%rsi
0x0c6:                      | L2:
0x0c6: 2078                 | 	rrmovq	%rdi, %r8
0x0c8: 2069                 | 	rrmovq	%rsi, %r9
0x0ca: 6189                 | 	subq	%r8, %r9
0x0cc: 71e000000000000000   | 	jle	L8
0x0d5: 2070                 | 	rrmovq	%rdi, %rax
0x0d7: 706b00000000000000   | 	jmp	L5
0x0e0:                      | L8:
0x0e0: 90                   | 	ret
                            | 
0x0c8:                      | .pos 200
0x0c8:                      | stack:

最后梳理以下本题要点:

Y86比较两个数只能用subq指令,不支持直接数运算并且减法后会改变第二个寄存器的值。比较时,一般将两个值保存在新的寄存器当中。

本答案仅依据 gcc -S -Og bubble_a.c 生成的文件改成Y86-64格式。源c文件的函数并没有问题,但是最终结果符不符合预期并没有检验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值