欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

反汇编三目运算与if,else

程序员文章站 2024-01-05 12:14:04
...

编译器(32位):MINGW gcc version 6.3.0 

反汇编命令:gcc -S -masm=intel -o  *.asm *.c (指定inter指令集)

建议写个批处理bat工具

@echo off 
REM make32.bat, return assembling fromConsole programs (.EXE)
::反汇编,%1为除批处理名称后的第一个参数
%MINGW_HOME%\bin\gcc -S -masm=intel -o  %1.asm %1.c 
::if errorlevel 值 cmmand 句式时,它的含义是:如果返回的错误码值大于或等于值 的时候,将执行cmmand
::goto跳转到批处理 :terminate  errorlevel上一条命令执行的返回码,1为执行错误,0为执行成功 echo %errorlevel%
if errorlevel 1 goto terminate 
DIR %1.*
:terminate
echo Input param of the c program
::批处理结束
@echo on 

1.三目运算反汇编

源码:

int a = 1,b = 2,c;
c = a > b ? 5:10;

反汇编代码:

	.file	"ThreeOperatorToAssmebly.c"
	.intel_syntax noprefix
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
	.globl	_main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
LFB10:
	.cfi_startproc
	push	ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	mov	ebp, esp
	.cfi_def_cfa_register 5
	and	esp, -16
	sub	esp, 16
	call	___main
	mov	DWORD PTR [esp+12], 1
	mov	DWORD PTR [esp+8], 2
	mov	eax, DWORD PTR [esp+12]
	cmp	eax, DWORD PTR [esp+8]
	jle	L2
	mov	eax, 5
	jmp	L3
L2:
	mov	eax, 10
L3:
	mov	DWORD PTR [esp+4], eax
	mov	eax, 0
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
LFE10:
	.ident	"GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"

2.if,else反汇编

源码

int a = 1,b = 2,c;
if(a > b){
   c = 5;
}else{
   c = 10;
}

 反汇编代码

	.file	"ThreeOperatorToAssmebly.c"
	.intel_syntax noprefix
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
	.globl	_main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
LFB10:
	.cfi_startproc
	push	ebp
	.cfi_def_cfa_offset 8
	.cfi_offset 5, -8
	mov	ebp, esp
	.cfi_def_cfa_register 5
	and	esp, -16
	sub	esp, 16
	call	___main
	mov	DWORD PTR [esp+12], 1
	mov	DWORD PTR [esp+8], 2
	mov	eax, DWORD PTR [esp+12]
	cmp	eax, DWORD PTR [esp+8]
	jle	L2
	mov	DWORD PTR [esp+4], 5
	jmp	L3
L2:
	mov	DWORD PTR [esp+4], 10
L3:
	mov	eax, 0
	leave
	.cfi_restore 5
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
LFE10:
	.ident	"GCC: (MinGW.org GCC-6.3.0-1) 6.3.0"

分析:

call	___main
	mov	DWORD PTR [esp+12], 1
	mov	DWORD PTR [esp+8], 2
	mov	eax, DWORD PTR [esp+12]
	cmp	eax, DWORD PTR [esp+8]
	jle	L2
	mov	DWORD PTR [esp+4], 5
	jmp	L3;无条件跳转至L3程序完成后续释放资源操作
L2:
	mov	DWORD PTR [esp+4], 10

只从call __main 调用main程序段来看

call    ___main
    mov    DWORD PTR [esp+12], 1;  DWORD PTR [esp+12]为指向内存中栈a变量,将1赋值于a
    mov    DWORD PTR [esp+8], 2  ; b = 2
    mov    eax, DWORD PTR [esp+12] ;将a变量移进寄存器eax
    cmp    eax, DWORD PTR [esp+8]  ;比较a,b大小
    jle    L2 ;若a小于b则跳转至L2执行,否则顺序执行
    mov    DWORD PTR [esp+4], 5 ;即a >b,将5移进指向在内存中地址为(栈顶址esp+4(int 4byte))的单元即c
L2:
    mov    DWORD PTR [esp+4], 10;赋值c为10

  

总结:

故三目运算其实也为逻辑判断,故与if,else判断执行效率无差。但if else逻辑清楚,多层if嵌套仍易快读懂逻辑

三目则为间接逻辑判断,多层三目运算不易读懂逻辑,且需赋值,但表达逻辑语句简单简洁。

例:

比较三个变量大小 return a>b?a>c?a:c:b>c?b:c