所以在下面的代码中,我试图打印好再见消息但是所有3个都被打印,如果添加了4个变量,它也会打印出来。 可能导致这种情况的原因以及如何解决这个问题。
我已经阅读了一些帖子,这些帖子提出了一些关于null终结符的内容,但使用
goodbyeMsg db " powering off",0
goodbyeMsg db " powering off$",10, 13, 0
goodbyeMsg db " powering off",10, 13, 0
goodbyeMsg db " powering off$"
无效
示例代码:
section .text
global _start
_start:
mov eax,4
mov ebx,1
mov ecx,goodbyeMsg
mov edx,lenGoodbyeMsg
int 80h
mov eax, 1
mov ebx ,0
int 80h
section .data
welcomeMsg db "Welcome, to Ugo Air Condition"
lenWelcomeMsg db $-lenWelcomeMsg
goodbyeMsg db " powering off"
lenGoodbyeMsg db $-lenGoodbyeMsg
help db "enter q w e r t y u "
lenHelp db $-lenHelp
quitKey db "q"
lenQuitKey equ $ - quitKey
defaultMode db "Stationary"
lenDefaultMode equ $-defaultMode
defaultTemp db 18
defaultFanSpeed db 2
section .bss
userInput resb 10
powerState resb 10
currentTemp resb 10
currentMode resb 10
currentFanSpeed resb 10
输出:
通过qStationarys
关闭电源strace的结果
execve("./air", ["./air"], [/* 58 vars */]) = 0
[ Process PID=5169 runs in 32 bit mode. ]
enter q w e r t y u qStationary) = 2048 "..., 134516943 powering off
_exit(0) = ?
+++ exited with 0 +++
答案 0 :(得分:2)
lenGoodbyeMsg db $-lenGoodbyeMsg
在数据部分中发出一个字节,值为0
(因为您使用的是lenGoodbyeMsg
而不是goodbyeMsg
)。
从e
标签后面的数据开头,数据部分跟随n
,t
和help:
的ASCII代码。如果您从lenGoodbyeMsg
加载了dword,那么您的数字就会非常大。
但这些数据都不重要,因为mov edx,lenGoodbyeMsg
将lenGoodbyeMsg
标签的地址放入edx,而那个大数字变为{{1}的长度arg }}。如果您在sys_write
下运行程序,则会看到一个非常大的长度传递给strace
。有点令人惊讶的是,sys_write不会在没有打印任何内容的情况下失败sys_write
;我猜它在检测到故障之前打印了第一页?
(或者您在重写代码后没有更新问题,这最初是In NASM labels next to each other in memory are causing printing issues的副本。)
如果你写的话, -EFAULT
将是正确的指示
mov edx,lenGoodbyeMsg
代替lenGoodbyeMsg equ $ - goodbyeMsg
,就像让每个汇编程序为您计算长度的工作示例一样。 因为那时db
将是汇编程序常量,而不是地址。
有关详细信息,请参阅How does $ work in NASM, exactly?。
当然,null终结符不起作用:你使用的是lenGoodbyeMsg
,它取一个指针+长度并处理任意二进制数据。
像sys_write
/ puts
/ printf
这样的C库函数采用空终止的隐式长度字符串。
答案 1 :(得分:0)
问题来自.data部分中编写的数据库。将它们更改为equ可以解决我的问题。谢谢大家的帮助。