汇编中的减法与补码转换奥秘

减法对应的汇编是sub。

虽然计算机指挥做加法但是,可以通过补码将减法转换为加法。

算式:y+y(反)=0-y<==>y(反+1)<==>-y<==>y(补)=-y

代码

#include <stdio.h>

int main(int argc, char* argv\[\]){
int n1 = argc;
int n2 = 0;
scanf("%d", &n2);
n1 = n1 - 100;
n1 = n1 + 5 - n2;
printf("n1 = %d\r\n", n1);

return 0;
}

汇编

wingw

main(int, char**):

push %rbp

mov %rsp,%rbp

sub $0x30,%rsp

mov %ecx,0x10(%rbp)

mov %rdx,0x18(%rbp)

call 0x7ff7f77b1827 ; <__main> mov 0x10(%rbp),%eax

mov %eax,-0x4(%rbp) ;n1 = argc

movl $0x0,-0x8(%rbp) ;n2 = 0

lea -0x8(%rbp),%rax

mov %rax,%rdx

lea 0x118f1(%rip),%rax ; 0x7ff7f77c3000 mov %rax,%rcx

call 0x7ff7f77c1b70 ; <scanf(char const*, ...)> subl $0x64,-0x4(%rbp) ;n1 = n1 - 100

mov -0x4(%rbp),%eax

add $0x5,%eax

mov -0x8(%rbp),%edx

sub %edx,%eax

mov %eax,-0x4(%rbp) ;n1 = n1 + 5 -n2

mov -0x4(%rbp),%eax

mov %eax,%edx

lea 0x118ce(%rip),%rax ; 0x7ff7f77c3003 mov %rax,%rcx

call 0x7ff7f77c1bd0 ; <printf(char const*, ...)> mov $0x0,%eax

add $0x30,%rsp

pop %rbp

ret

msvc

64->64

main(int,char **):

movq %rdx, 0x10(%rsp)

movl %ecx, 0x8(%rsp)

pushq %rdi

subq $0x50, %rsp

leaq 0x20(%rsp), %rdi

movl $0xc, %ecx

movl $0xcccccccc, %eax ; imm = 0xCCCCCCCC rep stosl %eax, %es:(%rdi) ;n1 = argc

movl 0x60(%rsp), %ecx

movl 0x60(%rsp), %eax

movl %eax, 0x20(%rsp)

movl $0x0, 0x34(%rsp) ;n2 = 0

leaq 0x34(%rsp), %rdx

leaq 0x8691(%rip), %rcx

callq 0x1400011a9 ; scanf movl 0x20(%rsp), %eax

subl $0x64, %eax ;n1 = n1 -100

movl %eax, 0x20(%rsp)

movl 0x20(%rsp), %eax

addl $0x5, %eax

subl 0x34(%rsp), %eax

movl %eax, 0x20(%rsp) ;n1 = n1 + 5 -- n2

movl 0x20(%rsp), %edx

leaq 0x866f(%rip), %rcx

callq 0x14000119a ; printf xorl %eax, %eax

movl %eax, %edi

movq %rsp, %rcx

leaq 0x86b4(%rip), %rdx

callq 0x140001046 ; _RTC_CheckStackVars movl %edi, %eax

addq $0x50, %rsp

popq %rdi

retq

64->32

main(int,char **):

pushl %ebp

movl %esp, %ebp

subl $0x10, %esp

movl $0xcccccccc, %eax ; imm = 0xCCCCCCCC movl %eax, -0x10(%ebp)

movl %eax, -0xc(%ebp)

movl %eax, -0x8(%ebp)

movl %eax, -0x4(%ebp)

movl 0x8(%ebp), %eax

movl %eax, -0x4(%ebp)

movl $0x0, -0xc(%ebp)

leal -0xc(%ebp), %ecx

pushl %ecx

pushl 0x197b30 *; imm = 0x197B30* calll 0x4010eb *; _scanf* addl 0x8, %esp

movl -0x4(%ebp), %edx

subl $0x64, %edx

movl %edx, -0x4(%ebp)

movl -0x4(%ebp), %eax

addl $0x5, %eax

subl -0xc(%ebp), %eax

movl %eax, -0x4(%ebp)

movl -0x4(%ebp), %ecx

pushl %ecx

pushl 0x197b34 *; imm = 0x197B34* calll 0x40119f *; _printf* addl 0x8, %esp

xorl %eax, %eax

pushl %edx

movl %ebp, %ecx

pushl %eax

leal 0x19155c, %edx

calll 0x401050 ; @_RTC_CheckStackVars@8 popl %eax

popl %edx

addl $0x10, %esp

cmpl %esp, %ebp

calll 0x4010ff ; __RTC_CheckEsp movl %ebp, %esp

popl %ebp

retl

addl %eax, (%eax)

addb %al, (%eax)

adcl $0xfff40019, %eax ; imm = 0xFFF40019

相关推荐
冻柠檬飞冰走茶10 小时前
字母移动游戏题解:贪心求最长可保留连续子串(附 C 实现)
c语言·开发语言·数据结构·算法·动态规划
FRing0311 小时前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
雪落漂泊11 小时前
C++算法 二分查找篇(上)
开发语言·c++·算法
波力海苔夹心脆67512 小时前
C# WPF 资源字典详解:ResourceDictionary、MergedDictionaries 与自定义控件案例
开发语言·c#·wpf·入门教程·resource·资源字典
不会算法的笨小孩12 小时前
异常的使用以及会出现的问题
开发语言·c++·c++11·异常
Hhy_110714 小时前
《C++深度解构06》手撕 string —— 从底层内存管理到深浅拷贝彻底吃透
c语言·开发语言·c++·学习·visual studio
starzy199014 小时前
深入理解Scala函数定义:从方法到函数的类型跨越
开发语言·scala
starzy199014 小时前
深入理解Scala递归函数:从栈溢出到尾调用优化
开发语言·scala
三*一15 小时前
Mapbox‑GL JS 多边形折点编辑工具:实现原理、功能拆解与踩坑总结
开发语言·javascript·ecmascript
YSL07012415 小时前
C++基础
开发语言·c++