为什么在 asm 中只要求一个时打印所有声明的变量
why do all the declared variable print when only one was asked for in asm
所以在下面的代码中,我试图只打印再见消息,但所有 3 个都被打印出来,如果添加了 4 个变量,它也会被打印出来。
是什么原因造成的,我该如何解决。
我读过一些关于空终止符的帖子,但是使用
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
输出:
给罪犯 q w e r t y u 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 +++
lenGoodbyeMsg db $-lenGoodbyeMsg
在数据部分发出 一个 字节,值为 0
(因为你使用 lenGoodbyeMsg
而不是 goodbyeMsg
).
在数据部分中,e
、n
和 t
的 ASCII 代码从 help:
标签后面的数据开始。如果你从 lenGoodbyeMsg
加载了一个双字,你会得到一个非常大的数字。
但是 none 的数据甚至很重要,因为 mov edx,lenGoodbyeMsg
将 lenGoodbyeMsg
标签的 地址 放入 edx,并且那个大number 变为 sys_write
的长度 arg。如果你 运行 你的程序在 strace
下,你会看到一个非常大的长度被传递给 sys_write
。有点令人惊讶的是 sys_write 不仅在 -EFAULT
时失败而且没有打印任何内容;我猜它在检测到错误之前打印了第一页?
(否则您在重写代码后没有更新问题,该代码最初是 In NASM labels next to each other in memory are causing printing issues 的副本。)
mov edx,lenGoodbyeMsg
如果你写
将是正确的指令
lenGoodbyeMsg equ $ - goodbyeMsg
而不是 db
,就像让汇编程序为您计算长度的每个工作示例一样。 因为 lenGoodbyeMsg
将是一个汇编程序常量,而不是地址。
有关详细信息,请参阅 How does $ work in NASM, exactly?。
当然,空终止符不起作用:您使用的是 sys_write
,它采用指针 + 长度并适用于任意二进制数据。
像 puts
/ printf
/ strstr
这样的 C 库函数采用空终止的隐式长度字符串。
问题出在.data段中写入的db。将它们更改为 equ 解决了我的问题。感谢大家的帮助。
所以在下面的代码中,我试图只打印再见消息,但所有 3 个都被打印出来,如果添加了 4 个变量,它也会被打印出来。 是什么原因造成的,我该如何解决。
我读过一些关于空终止符的帖子,但是使用
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
输出:
给罪犯 q w e r t y u 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 +++
lenGoodbyeMsg db $-lenGoodbyeMsg
在数据部分发出 一个 字节,值为 0
(因为你使用 lenGoodbyeMsg
而不是 goodbyeMsg
).
在数据部分中,e
、n
和 t
的 ASCII 代码从 help:
标签后面的数据开始。如果你从 lenGoodbyeMsg
加载了一个双字,你会得到一个非常大的数字。
但是 none 的数据甚至很重要,因为 mov edx,lenGoodbyeMsg
将 lenGoodbyeMsg
标签的 地址 放入 edx,并且那个大number 变为 sys_write
的长度 arg。如果你 运行 你的程序在 strace
下,你会看到一个非常大的长度被传递给 sys_write
。有点令人惊讶的是 sys_write 不仅在 -EFAULT
时失败而且没有打印任何内容;我猜它在检测到错误之前打印了第一页?
(否则您在重写代码后没有更新问题,该代码最初是 In NASM labels next to each other in memory are causing printing issues 的副本。)
mov edx,lenGoodbyeMsg
如果你写
将是正确的指令
lenGoodbyeMsg equ $ - goodbyeMsg
而不是 db
,就像让汇编程序为您计算长度的每个工作示例一样。 因为 lenGoodbyeMsg
将是一个汇编程序常量,而不是地址。
有关详细信息,请参阅 How does $ work in NASM, exactly?。
当然,空终止符不起作用:您使用的是 sys_write
,它采用指针 + 长度并适用于任意二进制数据。
像 puts
/ printf
/ strstr
这样的 C 库函数采用空终止的隐式长度字符串。
问题出在.data段中写入的db。将它们更改为 equ 解决了我的问题。感谢大家的帮助。