Linux 汇编;参数列表失控
我对任何类型的汇编编程都很陌生,而且因为我听说 Linux 的 NASM 类型汇编比基于 DOS 的汇编相对简单,所以我决定尝试一下。
到目前为止,这是我的程序:
section .data
opening: db 'Opening file...',10
openingLen: equ $-opening
opened: db 'File opened.',10
openedLen: equ $-opened
bad_params: db 'Usage: writeFile filename.ext',10
bad_paramsLen: equ $-bad_params
not_opened: db 'Unable to open file. Halted.',10
not_openedLen: equ $-not_opened
hello: db 'Hello, this is written to a file'
helloLen: equ $-hello
success: db 'Successfully wrote to file.',10
successLen: equ $-success
section .bss
file: resd 1
section .text
global _start:
_start:
pop ebx ; pop number of params
test ebx,2 ; make sure there are only 2
jne bad_param_list
pop ebx
mov eax,4 ; write out opening file msg
mov ebx,1
mov ecx,opening
mov edx,openingLen
int 80h
mov eax,5 ; open file
pop ebx
mov ecx,64
mov edx,777o ; permissions of file
int 80h
mov dword [file],eax
test dword [file],0
jle bad_open
mov eax,4 ; write successful open message
mov ebx,1
mov ecx,opened
mov edx,openedLen
int 80h
mov ebx,file ; write to file (4 already in eax)
mov ecx,hello
mov edx,helloLen
int 80h
mov eax,6 ; close file
mov ebx,file
int 80h
mov eax,4 ; write successfully written msg
mov ebx,1
mov ecx,success
mov edx,successLen
int 80h
mov eax,1 ; exit
mov ebx,0
int 80h
bad_param_list:
mov eax,4 ; write that params are bad
mov ebx,1
mov ecx,bad_params
mov edx,bad_paramsLen
int 80h
mov eax,1 ; exit with code 1
mov ebx,1
int 80h
bad_open:
mov eax,4 ; write that we couldn't open the file
mov ebx,1
mov ecx,not_opened
mov edx,not_openedLen
int 80h
mov eax,1 ; exit with code 2
mov ebx,2
int 80h
目标是将一串文本写入没有库函数的文件;我只使用 Linux 内核。我遇到了一些问题,比如到处缺少括号,以及所有其他错误,这些错误都是你从菜鸟到汇编所期望的,但我认为现在这基本上已经得到控制。
这是我的问题:据我所知,该程序的前四行应该将参数数量从堆栈中弹出,如果不仅有一个参数(除了程序名称),则跳转到 bad_param_list
,并将程序名称从堆栈中弹出。
但事实并非如此。下面是一些示例 I/O,为了清晰起见,重新格式化了:
$./writeFile
Opening file...
Unable to open file. Halted.
$./writeFile x
Usage: writeFile filename.ext
$./writeFile x x
Usage: writeFile filename.ext
$./writeFile x x x
Opening file...
Unable to open file. Halted.
$./writeFile x x x x
Opening file...
Unable to open file. Halted.
$./writeFile x x x x x
Usage: writeFile filename.ext
$./writeFile x x x x x x
Usage: writeFile filename.ext
我注意到,如果您采用包括程序名称在内的参数数量,除以 2,并丢弃小数,如果答案是奇数,您将收到我的使用错误,但如果答案是偶数,您将收到无法打开错误。至少 10 个参数之前都是如此!
我到底是怎么做到这一点的?以及如何让它达到预期的结果?
I'm new to programming in any sort of assembly, and since I've heard that NASM-type assembly for Linux is comparatively simple to DOS based assembly, I decided to give it a try.
This is my program thus far:
section .data
opening: db 'Opening file...',10
openingLen: equ $-opening
opened: db 'File opened.',10
openedLen: equ $-opened
bad_params: db 'Usage: writeFile filename.ext',10
bad_paramsLen: equ $-bad_params
not_opened: db 'Unable to open file. Halted.',10
not_openedLen: equ $-not_opened
hello: db 'Hello, this is written to a file'
helloLen: equ $-hello
success: db 'Successfully wrote to file.',10
successLen: equ $-success
section .bss
file: resd 1
section .text
global _start:
_start:
pop ebx ; pop number of params
test ebx,2 ; make sure there are only 2
jne bad_param_list
pop ebx
mov eax,4 ; write out opening file msg
mov ebx,1
mov ecx,opening
mov edx,openingLen
int 80h
mov eax,5 ; open file
pop ebx
mov ecx,64
mov edx,777o ; permissions of file
int 80h
mov dword [file],eax
test dword [file],0
jle bad_open
mov eax,4 ; write successful open message
mov ebx,1
mov ecx,opened
mov edx,openedLen
int 80h
mov ebx,file ; write to file (4 already in eax)
mov ecx,hello
mov edx,helloLen
int 80h
mov eax,6 ; close file
mov ebx,file
int 80h
mov eax,4 ; write successfully written msg
mov ebx,1
mov ecx,success
mov edx,successLen
int 80h
mov eax,1 ; exit
mov ebx,0
int 80h
bad_param_list:
mov eax,4 ; write that params are bad
mov ebx,1
mov ecx,bad_params
mov edx,bad_paramsLen
int 80h
mov eax,1 ; exit with code 1
mov ebx,1
int 80h
bad_open:
mov eax,4 ; write that we couldn't open the file
mov ebx,1
mov ecx,not_opened
mov edx,not_openedLen
int 80h
mov eax,1 ; exit with code 2
mov ebx,2
int 80h
The goal is to write a string of text to a file without library functions; I'm only using the Linux kernel. I had a few problems with missing brackets here and there, and all the rest of mistakes that you'd expect from a noob to assembly, but I think this is mostly under control now.
Here's my issue: From what I know, the first four lines of this program should pop the number of arguments off the stack, jump to bad_param_list
if there is not only one parameter (aside from the program name), and pop the program name off the stack.
But this is not what happens. Here's some sample I/O, reformatted for clarity:
$./writeFile
Opening file...
Unable to open file. Halted.
$./writeFile x
Usage: writeFile filename.ext
$./writeFile x x
Usage: writeFile filename.ext
$./writeFile x x x
Opening file...
Unable to open file. Halted.
$./writeFile x x x x
Opening file...
Unable to open file. Halted.
$./writeFile x x x x x
Usage: writeFile filename.ext
$./writeFile x x x x x x
Usage: writeFile filename.ext
What I've noticed is that if you take the number of arguments including the name of the program, divide by 2, and discard the decimal, if the answer is odd, you'll get my usage error, but if the answer is even, you'll get the unable to open error. This is true up until at least 10 arguments!
How the heck did I manage to do this? And how do I get it to have the expected result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不
除了设置标志之外,您
希望
test
在参数之间执行按位 AND 并丢弃结果。因此,如果两个参数在匹配的位置上没有 1 位,则特别会设置 ZF。 (在您的特定情况下,这相当于将 ZF 设置为 ebx 的倒数第二位的补码)。相反,
cmp
减去其参数并在设置标志后丢弃结果。在这种情况下,如果两个参数相等,则将设置 ZF。Instead of
you want
test
performs a bitwise AND between the arguments and throws the result away, except for setting the flags. So, in particular ZF will be set if the two arguments have no 1-bits in positions that match. (In your particular case, this works out as setting ZF to the complement of the second-to-lowest bit ofebx
).Conversely
cmp
subtracts its arguments and throws away the result after setting flags. In that case, ZF will be set if the two arguments are equal.