英文:
Why am I not getting output when I run the following assembly
问题
我需要使用x86 64位英特尔处理器。
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, "hello"
mov rdx, 5
syscall
mov rax, 60
xor rdi, rdi
syscall
我希望在终端中打印出"hello"。谢谢您的帮助。
英文:
I am required to use x86 64 bit intel
section .text
global _start
_start:
mov rax, 1
mov rdi, 1
mov rsi, "hello"
mov rdx, 5
syscall
mov rax, 60
xor rdi, rdi
syscall
I was hoping for hello to print in the terminal. Thanks for any assistance
答案1
得分: 3
指令mov rsi, "hello"
不适用于你想要做的事情。如果你查看这样一个指令生成的代码,你会看到:
00000010 48 BE 68 65 6C 6C 6F 00 00 00 mov rsi, "hello"
48BE
是将rsi
加载为立即数,并且它使用了hello
中字符的ASCII值(用零填充)来形成地址(68 = 'h'
,65 = 'e'
,6c = 'l'
,6f = 'o'
)。这个内存地址非常不可能包含任何有用的内容,更不用说你想要打印的单词的字符了。
相反,你应该定义一些内存来存储字符串,然后将rsi
加载为该地址,类似以下的方式:
section .text
global _start
_hello: db "hello", 10
_hello_sz: equ $ - _hello
_start: mov rax, 1
mov rdi, 1
mov rsi, _hello
mov rdx, _hello_sz
syscall
mov rax, 60
xor rdi, rdi
syscall
编译和运行这段代码会得到以下结果:
pax@hades-1> nasm -f elf64 -o progs.o progs.s
pax@hades-1> ld -o progs progs.o
pax@hades-1> ./progs
hello
你会注意到,我使用了一个公式来计算字符串的长度,这样你就可以随意更改它,而不必担心确保长度与之匹配,比如添加一个换行符10
以获得更好的输出
我也没有担心将字符串放入单独的数据段,因为作为常量,它可以留在代码段中而没有问题。然而,如果你希望这样做,可以参考下面的示例:
section .rodata
_hello: db "hello", 10
_hello_sz: equ $ - _hello
section .text
global _start
_start: mov rax, 1
:
等等。
英文:
The instruction mov rsi, "hello"
is not valid for what you want to do. If you look at the code generated by such a beast, you see:
00000010 48 BE 68 65 6C 6C 6F 00 00 00 mov rsi, "hello"
The 48BE
is an immediate load of rsi
and it's using the ASCII values of the characters in hello
(padded with zeros) to form the address (68 = 'h'
, 65 = 'e'
, 6c = 'l'
, and 6f = 'o'
). This memory address is very unlikely to hold anything useful at all, let alone the characters of the word you want to print.
Instead, you should define some memory to hold the string then load rsi
with the address of that, something like the following:
section .text
global _start
_hello: db "hello", 10
_hello_sz: equ $ - _hello
_start: mov rax, 1
mov rdi, 1
mov rsi, _hello
mov rdx, _hello_sz
syscall
mov rax, 60
xor rdi, rdi
syscall
Compiling and running this results in the following:
pax@hades-1> nasm -f elf64 -o progs.o progs.s
pax@hades-1> ld -o progs progs.o
pax@hades-1> ./progs
hello
You'll notice I've calculated the length of the string using a formula, allowing you to change it without worrying about ensuring the length is updated to match, such as adding a newline character 10
for nicer output
I've also not worried about putting the string into a separate data segment since, as a constant, it can stay in the code segment without issue. However, should you wish to do that, see the example below:
section .rodata
_hello: db "hello", 10
_hello_sz: equ $ - _hello
section .text
global _start
_start: mov rax, 1
:
and so on.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论