如何解决程序集“Hello world”程序分段错误
为什么会出现错误:
分段错误(核心转储)
这是汇编代码:
<Select
options={listType}
name="sanctionList"
placeholder="Select"
isMulti
styles={{
multiValueLabel: (base) => ({
...base,backgroundColor: "#0bb7a7",color: "white",fontSize: "0.8vw",borderRadius: 5,}),control: (data) => ({
...data,fontFamily: "Montserrat",borderColor: "#adadad",menu: (data) => ({
...data,}}
// isDisabled={!ListSel}
value={ListS}
onChange={(e) => changeList({ selected: e })}
theme={(theme) => ({
...theme,colors: {
...theme.colors,text: "black",primary25: "#d6fdf7",primary: "#0bb7a7",primary50: "#d6fdf7",},})}
></Select>
解决方法
问题
System V ABI 要求您在调用函数之前将堆栈对齐为 16 字节。为了简单起见,ABI 保证“在函数入口,如果你用 8 * n(n 是奇数)子你的堆栈指针,你的堆栈将是 16 字节对齐的”。
如果您不遵循此调用约定,其他库可能会崩溃,因为如果它们需要使用需要特殊对齐的指令(例如 movdqa
),它们无法正确对齐其堆栈帧。
解决方案
ammarfaizi2@integral:/tmp/test_asm$ cat test.S
.intel_syntax noprefix
.data
message: .asciz "Hello World!\n"
.text
.global main
main:
sub rsp,8
xor eax,eax
lea rdi,[rip + message]
call printf
add rsp,8
ret
ammarfaizi2@integral:/tmp/test_asm$ gcc test.S -o test
ammarfaizi2@integral:/tmp/test_asm$ ./test
Hello World!
ammarfaizi2@integral:/tmp/test_asm$
推荐
如果你 call
一个函数,接下来你要做的是 ret
,你可以用尾调用来简化代码。它使用 jmp
到要调用的目标函数。如果之前设置过,请确保在跳转前撤消当前函数堆栈帧。
为了支持 PIE 和 PIC,考虑使用 RIP 相对寻址来访问静态存储。它还提高了安全性。现在的编译器通常默认将目标编译为 PIE。
这部分是使用RIP相对寻址访问静态存储的例子:
lea rdi,[rip + message]
执行
ammarfaizi2@integral:/tmp/test_asm$ cat test.S
.intel_syntax noprefix
.data
message: .asciz "Hello World!\n"
.text
.global main
main:
xor eax,[rip + message]
jmp printf
ammarfaizi2@integral:/tmp/test_asm$ gcc test.S -o test
ammarfaizi2@integral:/tmp/test_asm$ ./test
Hello World!
ammarfaizi2@integral:/tmp/test_asm$
编辑
为了安全,添加了 xor eax,eax
。请参阅:glibc scanf Segmentation faults when called from a function that doesn't align RSP
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。