打印功能(获取分段错误)
printing function (get segmentation fault)
我正在尝试打印一个函数输出 W - X) + (Y - Z),我保留
每当我编译时出现分段错误(核心转储)
并尝试 运行 程序
nasm-felf64asm_program-oasm_program.o
gcc -m64 asm_program.o -o asm_program
./asm_program
我已经四处搜索,但无法找到解决方案。我想首先问这个分段错误是什么意思以及它与我的程序有什么关系,其次我的代码哪里出错了。
顺便说一句,对汇编比较陌生
程序从这里开始
global main
extern printf
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
compute:
mov rax, w
mov rcx, x
add rax,rcx
mov rbx, y
mov rbp, z
add rbx, rbp
mul rbx
call printf
更大的问题是:你永远不会打电话给 ret
:
global main
extern printf
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
ret ; added, or computed is executed a second time
compute:
mov rax, w
mov rcx, x
add rax,rcx
mov rbx, y
mov rbp, z
add rbx, rbp
mul rbx
call printf
ret ; added or program continues executing in the bush
之后,我们需要查看 printf
的 API 以确保使用正确的参数调用它(寄存器或堆栈已正确初始化)。如果这是我知道的 printf
,它是一个可变参数函数,需要像 "%d"
这样的格式然后是参数。我在你的代码中没有看到任何格式。
要打印一个简单的整数,我会避免使用 printf
并在使用自定义整数 => 字符串代码后逐字符输出结果。它会让你的代码更小、更独立(汇编并不是一直调用 C 函数:))。
你的公式 (w-x) + (y-z) 原则上与表示 (w+x) * (y+z) 的代码冲突所以这就是为什么我要给你一个例子。
mov rax, w Move the address of w into RAX which is 0x601038
mov rax, [w] Moves the value @ 0x601038 which is 1.
我们要查找的结果是 28,所以这就可以了。
global main
extern printf
segment .rodata
Fmt db 13, 10, 9, 'Result is %d', 13, 10, 13, 10, 0
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
ret ; added, or computed is executed a second time
compute:
mov rax, [w]
add rax, [x]
mov rcx, rax
mov rax, [y]
add rax, [z]
xor rdx, rdx
mul rcx
mov rdi, Fmt ; Format string
mov rsi, rax ; Value to be displayed
call printf
ret ; added or program continues executing in the bush
有很多方法可以给这只猫蒙皮,这只是一个简单的例子。
我正在尝试打印一个函数输出 W - X) + (Y - Z),我保留 每当我编译时出现分段错误(核心转储) 并尝试 运行 程序
nasm-felf64asm_program-oasm_program.o
gcc -m64 asm_program.o -o asm_program
./asm_program
我已经四处搜索,但无法找到解决方案。我想首先问这个分段错误是什么意思以及它与我的程序有什么关系,其次我的代码哪里出错了。
顺便说一句,对汇编比较陌生
程序从这里开始
global main
extern printf
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
compute:
mov rax, w
mov rcx, x
add rax,rcx
mov rbx, y
mov rbp, z
add rbx, rbp
mul rbx
call printf
更大的问题是:你永远不会打电话给 ret
:
global main
extern printf
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
ret ; added, or computed is executed a second time
compute:
mov rax, w
mov rcx, x
add rax,rcx
mov rbx, y
mov rbp, z
add rbx, rbp
mul rbx
call printf
ret ; added or program continues executing in the bush
之后,我们需要查看 printf
的 API 以确保使用正确的参数调用它(寄存器或堆栈已正确初始化)。如果这是我知道的 printf
,它是一个可变参数函数,需要像 "%d"
这样的格式然后是参数。我在你的代码中没有看到任何格式。
要打印一个简单的整数,我会避免使用 printf
并在使用自定义整数 => 字符串代码后逐字符输出结果。它会让你的代码更小、更独立(汇编并不是一直调用 C 函数:))。
你的公式 (w-x) + (y-z) 原则上与表示 (w+x) * (y+z) 的代码冲突所以这就是为什么我要给你一个例子。
mov rax, w Move the address of w into RAX which is 0x601038
mov rax, [w] Moves the value @ 0x601038 which is 1.
我们要查找的结果是 28,所以这就可以了。
global main
extern printf
segment .rodata
Fmt db 13, 10, 9, 'Result is %d', 13, 10, 13, 10, 0
segment .data
w: DQ 1
x: DQ 3
y: DQ 5
z: DQ 2
segment .text
main:
call compute
ret ; added, or computed is executed a second time
compute:
mov rax, [w]
add rax, [x]
mov rcx, rax
mov rax, [y]
add rax, [z]
xor rdx, rdx
mul rcx
mov rdi, Fmt ; Format string
mov rsi, rax ; Value to be displayed
call printf
ret ; added or program continues executing in the bush
有很多方法可以给这只猫蒙皮,这只是一个简单的例子。