【发布时间】:2021-03-05 01:43:42
【问题描述】:
这将是一个非常电流表的问题。但我是汇编编码的新手,所以请耐心等待。
我正在尝试将打印功能作为在程序集中打印数字的库(at&t,x86_64) 使用系统调用(写入函数/重定向到标准输出)。 lib 文件链接到调用函数的主文件,打印值在调用函数 printNumber 之前存储在 rax 寄存器中。
库中的代码
.global num, printNumber
.section .data
num: .quad 0
.section .text
printNumber:
mov %rax, %r9
mov $10, %r8
printTop:
xor %rax, %rax
xor %rdx, %rdx
mov %r9, %rax
div %r8
mov %rdx, $num
add $0x30, $num
mov %rax, %r9
mov $1, %rax
mov $1, %rdi
mov $1, %rdx
mov $num, %rsi
syscall
cmp $0, %r9
jne printTop
ret
问题是我似乎无法写入变量:num。
mov %rdx, num
add $0x30, num
当我将它用作 lib 时,是否会出现错误分段错误, 但是当我将它用作普通的可执行文件时,它就可以工作了。
所以我的问题是如何重写里面的值并打印出来?
num: .quad 0
如果没有办法重写汇编中的值,如何将值指向标准输出
mov $1, %rax // Write syscall
mov $1, %rdi // fd where to write/stdout
mov $1, %rdx // Number of values to write
mov $num, %rsi // Pointer to where the output starting from
syscall
已尝试使用该值设置 rbx 寄存器,但不会打印任何内容,我猜所有寄存器都已为系统调用清除,不能用作持有者。
mov $num, %rsi
to
mov %rbx, %rsi
//注意: 我知道这个函数只会打印反转的无符号整数, 但我目前正在尝试解决写入问题。
我也尝试过寻找解决方案,但很多都是 x86 或英特尔架构。
主代码
.data
format: .asciz "%d\n"
c: .quad 0
.text
.globl main
main:
push $1337
pop c
push c
pop %rax
call printNumber
movq $60, %rax
movq $0, %rdi
syscall
构建
Lib build.
gcc libCalc.s -no-pie -nostdlib -o libCalc.o
ar rcs ../lib/libCalc.a libCalc.o
Build and link.
gcc -no-pie -o bin/file file.s lib/libCalc.a
【问题讨论】:
-
$num表示num的地址。你显然无法改变这一点。如果要引用该值,则不能使用$。如果你这样做,你会得到什么错误?你只是说“当我删除 $ 符号时我得到了这个工作,但不是作为一个普通的可执行文件作为一个 lib 文件。”它应该在一个 lib 中工作。 -
我得到分段错误,如果我删除 mov %rdx, num 并添加 $0x30, num 我什么也得不到,谢谢顺便说一句 $ 注释我用错了。
-
嗯,这是一个不同的问题。 edit 您对该代码的问题以及来自调试器的有关故障所在的信息。还要展示你是如何调用它的,以及你是如何组装和链接的。
-
无论如何,这听起来像是您设法以某种方式将
num放入只读部分。仔细检查这是您正在运行的确切代码,并且您有.section .data,如图所示(或只是.data)。 -
@Jester:shared 库不能使用 32 位绝对寻址模式,也许他们试图将静态库链接到 PIE 可执行文件。
mov %rdx, num使用 32 位绝对寻址模式,与mov %rdx, num(%rip)不同。
标签: assembly x86-64 static-libraries