当我运行以下汇编代码时,为什么没有输出?

huangapple go评论82阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年8月9日 07:52:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76863770.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定