欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 幼教 > 《汇编语言程序设计》例子出现segmentation fault

《汇编语言程序设计》例子出现segmentation fault

2024/10/24 1:55:45 来源:https://blog.csdn.net/tianyexing2008/article/details/139688311  浏览:    关键词:《汇编语言程序设计》例子出现segmentation fault

        照着例子抄写了一下,直接用的 gcc 编译,源码如下,因为不支持 pushl,所以改成了 pushq

#cpuid.s View the CPUID Vendor ID string using C library calls
.section .data
output:.asciz "The processor Vendor ID is %s \n".section .bss.lcomm buffer, 12.section .text
.global main
main:MOVL $0, %eaxcpuidMOVL $buffer, %edi 	MOVL %ebx, (%edi)MOVL %edx, 4(%edi)MOVL %ecx, 8(%edi)pushq $bufferpushq $outputcall printfaddl $8, %esppushq $0call exit

如果使用 pushl 的话,在x86_64 位下不支持,如下错误信息:

 网上搜索到解决办法有 2 种,一种是在源码开头添加.code32 告诉编译器按照32位进行编译,另外一种是使用 pushq,q 即为 quad word 表示 8 字节长度的,即 64 位。编译通过后,运行时出现 segmentation fault。网上搜了很多,没有一样的,但很多相似的在调用 printf 的时候出现 segmentation fault,这个跟调用约定有关系,64 位和32 位还不一样,64 位下是通过寄存器和栈来传递参数的,而 32 位下则是通过栈来传递参数的。看上面的代码 pushq $buffer 和  pushq $output 就是入栈操作,而在 64 位下:整数参数(包含指针)依次放在 %rdi, %rsi, %rdx, %rcx, %r8, 和 %r9 寄存器中,如果调用的是可变参数的函数(比如printf), 寄存器%eax需记录下浮点参数的个数,找到一段可用的代码,修改如下:

.section .data
output:.string "The processor Vendor ID is %s \n".section .bss.lcomm buffer, 32.section .text
.global main
main:MOVL $0, %eaxcpuidMOVL $buffer, %edi 	MOVL %ebx, (%edi)MOVL %edx, 4(%edi)MOVL %ecx, 8(%edi)MOVQ $output, %rdi	#需要用MOVQ 来操作64bit寄存器MOVQ $buffer, %rsi	#同上MOVQ $0, %rax		#同上pushq %r10pushq %r11call printfpopq %r11popq %r10ret

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com