关于 test 和 setg 的汇编代码

今天看反汇编,发现了这样的汇编代码

    4015ab:	84 c0                	test   %al,%al
    4015ad:	0f 9f c0             	setg   %al
    4015b0:	84 c0                	test   %al,%al

怎么看也没看明白这段代码是干什么的。于是写了一些测试代码来推测这段代码的用途

测试结论

这段汇编会检验 %al 寄存器的值。如果该寄存器的值小于等于 0 则在执行完这三行汇编后,%al 置为 1 ;否则置为 0

测试过程

首先先编写 b.c 文件

int f(char c){ return 0;}

然后使用 gcc 将其转化为汇编代码。

因为这样产生的汇编代码才会有和 gcc 最好的兼容性。

gcc b.c -S -o b.o

修改产生的汇编代码,在其中加入自己想要插入的汇编代码。

	.file	"b.c"
	.text
	.p2align 4,,15
	.globl	f
	.def	f;	.scl	2;	.type	32;	.endef
	.seh_proc	f
f:
	.seh_endprologue
    mov %cl, %al
    test %al, %al
    setg %al
	test %al, %al
	jne .L1
	mov $0x1, %rax
	ret
.L1:
	mov $0x0, %rax
	ret
	.seh_endproc
	.ident	"GCC: (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0"

然后创建 main.c 文件,在此之前需要删掉 b.c 文件中 f() 函数的实现。下面是两个文件的代码。

// b.c
int f(char a);
// main.c
#include <stdio.h>
#include <stdlib.h>

#include "b.c"

int main(){
    char c = 0;
    printf("%d, %d\n", (int)(c), f(c));
    for (c++; c!=0; c++){
        printf("%d, %d\n", (int)(c), f(c));
    }
    return 0;
}

然后链接 b.smain.c 文件,并执行 main 文件。

gcc b.s main.c -o main
./main

执行结果如下。

0, 1
1, 0
2, 0
3, 0
4, 0
5, 0
6, 0
7, 0
8, 0
9, 0
10, 0
11, 0
12, 0
13, 0
14, 0
15, 0
16, 0
17, 0
18, 0
19, 0
20, 0
21, 0
22, 0
23, 0
24, 0
25, 0
26, 0
27, 0
28, 0
29, 0
30, 0
31, 0
32, 0
33, 0
34, 0
35, 0
36, 0
37, 0
38, 0
39, 0
40, 0
41, 0
42, 0
43, 0
44, 0
45, 0
46, 0
47, 0
48, 0
49, 0
50, 0
51, 0
52, 0
53, 0
54, 0
55, 0
56, 0
57, 0
58, 0
59, 0
60, 0
61, 0
62, 0
63, 0
64, 0
65, 0
66, 0
67, 0
68, 0
69, 0
70, 0
71, 0
72, 0
73, 0
74, 0
75, 0
76, 0
77, 0
78, 0
79, 0
80, 0
81, 0
82, 0
83, 0
84, 0
85, 0
86, 0
87, 0
88, 0
89, 0
90, 0
91, 0
92, 0
93, 0
94, 0
95, 0
96, 0
97, 0
98, 0
99, 0
100, 0
101, 0
102, 0
103, 0
104, 0
105, 0
106, 0
107, 0
108, 0
109, 0
110, 0
111, 0
112, 0
113, 0
114, 0
115, 0
116, 0
117, 0
118, 0
119, 0
120, 0
121, 0
122, 0
123, 0
124, 0
125, 0
126, 0
127, 0
-128, 1
-127, 1
-126, 1
-125, 1
-124, 1
-123, 1
-122, 1
-121, 1
-120, 1
-119, 1
-118, 1
-117, 1
-116, 1
-115, 1
-114, 1
-113, 1
-112, 1
-111, 1
-110, 1
-109, 1
-108, 1
-107, 1
-106, 1
-105, 1
-104, 1
-103, 1
-102, 1
-101, 1
-100, 1
-99, 1
-98, 1
-97, 1
-96, 1
-95, 1
-94, 1
-93, 1
-92, 1
-91, 1
-90, 1
-89, 1
-88, 1
-87, 1
-86, 1
-85, 1
-84, 1
-83, 1
-82, 1
-81, 1
-80, 1
-79, 1
-78, 1
-77, 1
-76, 1
-75, 1
-74, 1
-73, 1
-72, 1
-71, 1
-70, 1
-69, 1
-68, 1
-67, 1
-66, 1
-65, 1
-64, 1
-63, 1
-62, 1
-61, 1
-60, 1
-59, 1
-58, 1
-57, 1
-56, 1
-55, 1
-54, 1
-53, 1
-52, 1
-51, 1
-50, 1
-49, 1
-48, 1
-47, 1
-46, 1
-45, 1
-44, 1
-43, 1
-42, 1
-41, 1
-40, 1
-39, 1
-38, 1
-37, 1
-36, 1
-35, 1
-34, 1
-33, 1
-32, 1
-31, 1
-30, 1
-29, 1
-28, 1
-27, 1
-26, 1
-25, 1
-24, 1
-23, 1
-22, 1
-21, 1
-20, 1
-19, 1
-18, 1
-17, 1
-16, 1
-15, 1
-14, 1
-13, 1
-12, 1
-11, 1
-10, 1
-9, 1
-8, 1
-7, 1
-6, 1
-5, 1
-4, 1
-3, 1
-2, 1
-1, 1

结论得证。

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值