汇编中call printf参数压栈时错误理解
EAX, ECX,EDX,EBX均可以32bit,16bit,8bit访问,如下所示:
<-------------------EAX------------------------>
|<----------------------|-----------|----------->|
|<---------AX--------->|
|<---AH--->|<---AL--->|
测试代码如下:
.section .data
output:
.asciz "Value is:%x\n"
val:
.int .section .text
.globl main
main:
nop
movl $0x12345678, %eax
movl $, %ecx
movw %ax, %cx
pushw %cx
pushl $output
call printf
addl $, %esp movl $, %eax
movl $, %ebx
int $0x80
我的电脑是小端格式(MSB存于高位),所以预期的输出结果是:0x5678,但是我编译执行后结果是:0x2dec5678,前面多出了2个字节,但是明明我压栈的时候使用的pushw,原来是printf获取参数时使用的是4字节长度,所以虽然我压入的只有2个字节,但是它访问时以4字节访问。
将代码修改:
.section .data
output:
.asciz "Value is:%x\n"
val:
.int .section .text
.globl main
main:
nop
movl $0x12345678, %eax
movl %eax, %ecx
pushl %ecx
pushl $output
call printf
addl $, %esp movl $, %ecx
movw %ax, %cx
pushl %ecx
pushl $output
call printf
addl $, %esp movl $, %eax
movl $, %ebx
int $0x80
预期输出:
Value is:12345678
Value is:5678
结果输出:
Value is:12345678
Value is:12
起先还以为是将0x12345678的最高字节0x12传送到cx里面了,觉得相当怪异,明明使用的是movw,要错也是0x1234,分析了下,原来又是printf作怪,函数调用后,其返回值一般是存储在eax里面来传递的,而第一个printf的输出:Value is:12345678恰好有0x12,18个字符(含'\n'),所以代码执行完15行的call后,eax的值已被printf的返回值修改,而不是我预期的0x12345678。所以汇编里面调用库函数时,要特别注意某些特殊寄存器的特殊用途,特别是这些库是由其他高级语言通过编译工具生成的时候。
汇编中call printf参数压栈时错误理解的更多相关文章
- C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)
上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...
- c/c++的函数参数压栈顺序
整理日:2015年3月18日 为了这句话丢了很多次人.无所谓了,反正咱脸皮厚. 总结一下 编译出来的c/c++程序的参数压栈顺序只和编译器相关! 下面列举了一些常见的编译器的调用约定 VC6 调用约定 ...
- printf函数压栈解惑
最近看到一些程序员的笔试题目,经常会考到printf函数的参数压栈问题,总体来讲就是参数从右向左依次压栈,再出栈,但是今天看到一个看似很简单的题目,却一直找不到头绪.题目如下: #include &l ...
- printf函数压栈(i++/i--,++i/--i) 终极解密
#include <stdio.h> void main() { ; printf("%d %d %d %d\n", i, --i, i, i--); } 输出是“3 ...
- printf()函数压栈a++与++a的输出
printf()中a++与++a的输出问题 在C语言中有个很常用的函数printf(),使用时从右向左压栈,也就是说在printf("%d %d %d %d\n",a,a++,++ ...
- iOS中的堆(heap)和栈(stack)的理解
操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...
- Fedora 20中解决zip解压文件时中文文件名的乱码问题[已解决]
该方法的原文地址: http://wangqige.com/the-solution-of-unzip-files-which-zip-under-windows/(链接已失效) 解决方法:保存如下P ...
- x86汇编寄存器,函数参数入栈说明
https://en.wikipedia.org/wiki/X86_calling_conventions
- arm汇编进入C函数分析,C函数压栈,出栈,传参,返回值
环境及代码介绍 环境和源码 由于有时候要透彻的理解C里面的一些细节问题,所有有必要看看汇编,首先这一切的开始就是从汇编代码进入C的main函数过程.这里不使用编译器自动生成的这部分汇编代码,因为编译器 ...
随机推荐
- 线段树区间求最大值(点更新)---I Hate It
HDU 1754 Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的 ...
- bootstrap 分页
1.背景: 前端页面使用bootstrap分页,同时与搜索条件联动: 2. jsp页面由服务端返回后, 异步请求动态创建表格, 分页的数据由服务端第一次返回后初始化, 以后每次异步请求再更新. jsp ...
- Python学习之Python简介
Python简介 Python的由来 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象.解释型计算机程序设计语言,它是吉多·范罗苏姆(Guide van ...
- ASP.NET Web API 通过Authentication特性来实现身份认证
using System; using System.Collections.Generic; using System.Net.Http.Headers; using System.Security ...
- saltstack学习笔记1 --安装
salt官网:http://docs.saltstack.cn/zh_CN/latest/ 安装教程: - http://docs.saltstack.cn/zh_CN/latest/topics/i ...
- SharePoint 2013 使用查阅项实现联动下拉框
SharePoint列表使用中,经常会用到下拉框,而有些特殊的需求,会用到联动的下拉框,在SharePoint中默认没有这样的字段,所以如果实现,我们需要自己想办法. 这里,我们介绍如何使用JQuer ...
- SharePoint 2010 文档管理系列之星级评论功能
前言:正如我们前面介绍的是,文档管理就是让大家更加直观.方便的对手里的文档,进行统筹掌控,哪些文档是有价值的,哪些文档更受大家欢迎,所有就带来了这个星级评论. 当然,这个是SharePoint 201 ...
- Xcode证书路径和缓存清理路径
1.Xcode证书路径: ~/Library/MobileDevice/Provisioning Profiles 2.Jenkines共享证书路径: /用户/共享/Jenkins/Library/M ...
- [linux]CentOS无法使用epel源
[linux]CentOS无法使用epel源 问题的产生与解决 作者作为Android应用开发者,对linux的接触一直是ubuntu为主,但是有一个用于科学上网的vps,由于内存只有64M,所以使用 ...
- storyBoard配置错误导致崩溃 superview]: unrecognized selector...
控制台打印崩溃原因 [TaskStartVC superview]: unrecognized selector sent to instance RT TaskStartVC是一个同storyBoa ...