【发布时间】:2021-04-08 22:35:05
【问题描述】:
我正在测试使用 .bss 分配内存区域以保存单个数字。然后将该号码打印到控制台。输出不如预期。我应该得到 e 数字 (12),但得到一个换行符。
系统配置:
$ uname -a
Linux 5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
description: CPU
product: Intel(R) Core(TM) i5-8350U CPU @ 1.70GHz
代码:
# compile with: gcc -ggdb -nostdlib -no-pie test.s -o test
.bss
.lcomm output,1
.global _start
.text
_start:
# test .bss and move numer 12 to rbx where memory are allocated in .bss
mov $output, %rbx # rbx to hold address of allocated space
mov $12,%rdx # Move a number to rdx
mov %rdx,(%rbx) # Move content in rdx to the address where rbx points to (e.g ->output)
# setup for write syscall:
mov $1,%rax # system call for write, according to syscall table (http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/)
mov $1,%rdi # fd = 1, stdout
mov $output,%rsi # adress of string to output moved to rsi
mov $1,%rdx # number of bytes to be written
syscall # should write 12 in console
mov $60,%rax
xor %rdi,%rdi
syscall # exit normally
我已经用第一个系统调用(使用 GDB)设置了一个断点,以查看寄存器:
i r rax rbx rdx rdi rsi
rax 0x1 1
rbx 0x402000 4202496
rdx 0x1 1
rdi 0x1 1
rsi 0x402000 4202496
x/1 0x402000
0x402000 <output>: 12
系统调用后的输出为空白,预计会得到数字“12”:
:~/Dokumenter/ASM/dec$ gcc -ggdb -nostdlib -no-pie test.s -o test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$ ./test
:~/Dokumenter/ASM/dec$
所以,我的问题是,是否有任何明显的解释来解释为什么我会变得空白而不是 12?
【问题讨论】:
-
它写入了字节 12,在 ASCII 中是换页符。如果你想看到
12这两个字符,你需要写这两个字符,例如1是 ASCII 码 49 (0x31)。write系统调用不会为您进行二进制到十进制的转换。 -
顺便说一句,您的
mov %rdx,(%rbx)将 8 个字节写入一个只有 1 空间的变量。您将要了解操作数大小。但是,这三个指令序列可以替换为movb $12, output。 -
谢谢,但即使我将大小增加到 8 (
.lcomm output,8),并写入不同的字节长度 (2,4,8) - (mov $8,%rdx),它仍然只是打印一个换行符.. 还简化了测试 movb 的代码,但结果相同.. (movb $12,output)mov $2,%rdx # number of bytes to be written -
是的,因为您现在正在写出两个字节
12, 0,它们不会显示为数字1和2;它是一个换页符,后跟一个空字符。你必须写出两个字节49, 50。要了解我的意思,请执行movb $49, output和movb $50, output+1。查看man ascii,看看哪些数值对应哪些字符。 -
你也可以写
movb $'1', output,汇编器会为你计算出正确的ASCII值。
标签: linux assembly gcc system-calls