- 论坛徽章:
- 0
|
在《深入了解计算机系统》(修订版)第126页中有个例题,给了你一段汇编代码,要求写出相应的c语言代码中的某些部分。所给的汇编代
码为
movl 8(%ebp), %ecx get a
movl 12(%ebp), %esi get b
cmpl %esi, %ecx
setl %al get t1
cmpl %ecx, %esi
setb -1(%ebp) get t2
cmpw %cx, 16(%ebp)
setge -2(%ebp)
movb %cl, %dl
cmpb 16(%ebp), %dl
setne %bl
cmpl %esi, 16(%ebp)
setg -3(%ebp)
testl %ecx, %ecx
setg %dl
addb -1(%ebp), %al
addb -2(%ebp), %al
addb %bl, %al
addb -3(%ebp), %al
addb %dl, %al
movsbl %al, %eax
所给的完整的的c语言代码为
char ctest(int a,int b,int c)
{
char t1=a<b;(此处要求填出<)
char t2=b<(unsigned)a;(此处要求填出<和unsigned转换)
char t3=(short)c>=(short)a;(此处要求填出>=和两个short转换)
char t4=(char)a!=(char)c;(此处要求填出!=和两个char转换)
char t5=a>b;(此处要求填出>)
char t6=a>0;(此处要求填出>)
return t1+t2+t3+t4+t5+t6;
}
上面我都填对了,但后来想想还有一些概念上的细节有些不确定
(1)set指令只针对单字节寄存器或者单字节存储器,而上面的-1(%ebp),-2(%ebp),-3(%ebp)只是制定了存储起始位置,具体大小应该是由
类型定义决定的。后来我小改了这个程序一下,编译了一下,发现我的猜测好像是对的。。。
(2)cmpw %cx, 16(%ebp)对应char t3=(short)c>=(short)a,似乎在把4字节的int型a转换为2字节的short型a时取了高2字节%cx,那么为什么取高两字节而不是低两字节呢?个人觉得可能跟这跟机器的大/小端规则有关,是否如此呢?
附:修改的c代码和汇编
c代码,全部改为int型
int testchar(int a,int b,int c)
{
int t1=a<b;
int t2=b<(unsigned)a;
int t3=(short)c>=(short)a;
int t4=(char)a!=(char)c;
int t5=c>b;
int t6=a>0;
return t1+t2+t3+t4+t5+t6;
}
汇编後
.file "testchar.c"
.text
.globl testchar
.type testchar,@function
testchar:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
setl %al
movzbl %al, %eax
movl %eax, -4(%ebp)
movl 12(%ebp), %eax
cmpl 8(%ebp), %eax
setb %al
movzbl %al, %eax
movl %eax, -8(%ebp)
movl 16(%ebp), %eax
cmpw 8(%ebp), %ax
setge %al
movzbl %al, %eax
movl %eax, -12(%ebp)
movb 8(%ebp), %al
cmpb 16(%ebp), %al
setne %al
movzbl %al, %eax
movl %eax, -16(%ebp)
movl 16(%ebp), %eax
cmpl 12(%ebp), %eax
setg %al
movzbl %al, %eax
movl %eax, -20(%ebp)
cmpl $0, 8(%ebp)
setg %al
movzbl %al, %eax
movl %eax, -24(%ebp)
movl -8(%ebp), %eax
addl -4(%ebp), %eax
addl -12(%ebp), %eax
addl -16(%ebp), %eax
addl -20(%ebp), %eax
addl -24(%ebp), %eax
leave
ret
.Lfe1:
.size testchar,.Lfe1-testchar
.ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" |
|