标签:
EAX, ECX,EDX,EBX均可以32bit,16bit,8bit访问,如下所示:
<-------------------EAX------------------------>
|<----------------------|-----------|----------->|
|<---------AX--------->|
|<---AH--->|<---AL--->|
测试代码如下:
1 .section .data 2 output: 3 .asciz "Value is:%x\n" 4 val: 5 .int 0 6 7 .section .text 8 .globl main 9 main: 10 nop 11 movl $0x12345678, %eax 12 movl $0, %ecx 13 movw %ax, %cx 14 pushw %cx 15 pushl $output 16 call printf 17 addl $6, %esp 18 19 movl $1, %eax 20 movl $0, %ebx 21 int $0x80
我的电脑是小端格式(MSB存于高位),所以预期的输出结果是:0x5678,但是我编译执行后结果是:0x2dec5678,前面多出了2个字节,但是明明我压栈的时候使用的pushw,原来是printf获取参数时使用的是4字节长度,所以虽然我压入的只有2个字节,但是它访问时以4字节访问。
将代码修改:
1 .section .data 2 output: 3 .asciz "Value is:%x\n" 4 val: 5 .int 0 6 7 .section .text 8 .globl main 9 main: 10 nop 11 movl $0x12345678, %eax 12 movl %eax, %ecx 13 pushl %ecx 14 pushl $output 15 call printf 16 addl $8, %esp 17 18 movl $0, %ecx 19 movw %ax, %cx 20 pushl %ecx 21 pushl $output 22 call printf 23 addl $8, %esp 24 25 movl $1, %eax 26 movl $0, %ebx 27 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。所以汇编里面调用库函数时,要特别注意某些特殊寄存器的特殊用途,特别是这些库是由其他高级语言通过编译工具生成的时候。
标签:
原文地址:http://www.cnblogs.com/thammer/p/4311621.html