汇编代码意外打印.shstrtab.text.data

问题描述 投票:0回答:3

虽然我有很多 C 和 C++ 经验,但我对汇编很陌生。 我的汇编代码应该像新语言中的所有第一个程序一样打印 hello world。 它打印出 hello world 但也打印出一些额外的文本:

hello world!
.shstrtab.text.data

这是我的汇编程序:

section .text
    global _start       ;for the linker
    
_start:
    mov edx, length     ; message length
    mov ecx, message    ; message to write
    mov ebx, 1      ; file descriptor stdout
    mov eax, 4      ; system call number
    int 0x80    ; call kernel
    
    mov eax, 1  ;system call number for sys_exit to exit program
    int 0x80    ; call kernel
    
section .data
message db "hello world!"
length DD 10

如果您知道如何解决此问题,请解释为什么会发生这种情况。 谢谢。

额外信息:我正在使用带有 ld 链接器的 nasm 汇编器

linux assembly x86 nasm ld
3个回答
0
投票

所以问题在于添加长度,因为它给出了长度变量的地址而不是值。答案是使用

move edx, [length]
。感谢杰斯特向我指出这一点


0
投票

长度等于 $ - 消息 |而不是长度 dd 10


0
投票

我会给你正确的代码并解释它。但是我的经验不够告诉你为什么你的代码不起作用。

这是正确的代码:

section .text
    global _start       ;for the linker
    
_start:
    mov edx, length     ; message length
    mov ecx, message    ; message to write
    mov ebx, 1      ; file descriptor stdout
    mov eax, 4      ; system call number
    int 0x80    ; call kernel
    
    mov eax, 1  ;system call number for sys_exit to exit program
    int 0x80    ; call kernel
    
section .data
message db "hello world!"
length equ $-message

message db "hello world!"
-
message
是一个标签,存储字符串“hello world!”的起始地址。

db
表示
define byte
,用于为标签
message
分配1个字节的空间。

需要记住的两件非常重要的事情:

  1. 指令被一次又一次地获取、解码和执行。
  2. 数据和指令存储在同一个内存中
这意味着“hello world”的每个字母都被写入内存地址

1 AFTER ANOTHER

写完所有字母

1乘1后,您将到达字符串的末尾

然后您将转到

下一个内存地址,其中保存下一条指令length equ $-message

length equ $-message

 中 - 
$
 代表当前地址。因此,您需要从 
字符串结尾 (message
) 中减去 
字符串开头 ($
)。

这将为您提供字符串的长度,甚至无需手动计算或编写。

我在你的代码中发现了一个错误,你写了

length DD 10

。现在 
length
 应该保持 
message
 的长度。

但是消息的长度

hello world!

是12而不是10。另一件事是
dd
意味着
define double word
,通常是4个字节,并且需要更多的内存空间来存储长度。 
这是您可以参考的指南。

希望这有帮助,祝你有美好的一天。😊😊

© www.soinside.com 2019 - 2024. All rights reserved.