【问题标题】:Using Assembly Language on Mac to Append a file在 Mac 上使用汇编语言附加文件
【发布时间】:2017-09-07 10:30:12
【问题描述】:

我一直在使用 Richard Blum 的“专业汇编语言”一书学习汇编,并通过在 MacOS 上编写汇编来完成所有这些,当然除了一些“使用文件”练习。具体来说,在附加文件时遇到问题。我可以写入文件,没问题,但不确定是否有正确的“访问模式值”来附加文件。根据 usr/include/sys/fcntl.h 文件,MacOS 喜欢使用 0x0008 来附加文件。 PAL 手册使用 $02002(八进制)。 (我想我可以尝试使用库函数来代替,但显然这些只是“int”系统调用的包装,只是试图了解这一切是如何工作的)。

感谢您的帮助,如果这是一个愚蠢的问题或做了一些非常愚蠢的事情,我们深表歉意。干杯。

这是我的代码:

.data
filename:
.asciz "cpuid.txt"
output:
.asciz "The processor Vendor ID is 'xxxxxxxxxxxx'\n"

.bss
.lcomm filehandle, 4

.text
.globl _main
_main:
movl $0, %eax

# Get the CPUID and place the CPUID values (stored in ebx, edx and ecx) accordingly within,
# the correct address space, after the 'output' address.
cpuid
movl $output, %edi
movl %ebx, 28(%edi)
movl %edx, 32(%edi)
movl %ecx, 36(%edi)


# OPEN/CREATE A FILE:
movl $5, %eax
movl $filename, %ebx
movl $0x0008, %ecx      # Access mode values loaded into ECX        
                        #.... APPEND TEXT FILE, using a $02002(octal) according to PAL textbook
                        # on MacOS, APPEND mode is 0x0008 or $00007(octal)?  according to usr/include/sys/fcntl.h
movl $0644, %edx        # file permission values loaded into EDX

# For MacOS, we need to put all of this on the stack (in reverse order),
# and, add an additional 4-bytes of space on the stack,
# prior to the system call (with 'int')
pushl %edx
pushl %ecx
pushl %ebx
subl  $4, %esp
int   $0x80             # ...make the system call
addl  $16, %esp         # clear the stack


test %eax, %eax         # check the error code returned (stored in EAX) after attempting to open/create the file
js badfile              # if the value was negative (i.e., an error occurred, then jump)
movl %eax, filehandle   # otherwise, move the error code to the 'filehandle'


# WRITE TO FILE:
movl $4, %eax
movl filehandle, %ebx
movl $output, %ecx
movl $42, %edx

# once again, for MacOS, put all of this on the stack,
# and, add an additional 4-bytes of space on the stack
pushl %edx
pushl %ecx
pushl %ebx
subl $4, %esp
int $0x80
addl $16, %esp          # and, again, clear the stack

test %eax, %eax
js badfile



# CLOSE THE FILE:
movl $6, %eax
movl filehandle, %ebx

# okay, move it onto the stack again (only one parameter on stack for closing this time)
pushl %ebx
subl $4, %esp
int $0x80

addl $8, %esp

badfile:
subl $9, %esp
movl %eax, %ebx
movl $1, %eax
int $0x80

【问题讨论】:

  • 在打开文件时将 $02001 放入 %ecx 似乎不起作用。如果我使用该访问模式代码然后尝试附加文件,则该文件似乎不会附加到 mac osx (MacOS) 中(尽管如果它为空,则能够写入“cpuid.txt”上方的文件)。
  • 如果 O_APPEND 在 mac 上是 0x8,那么我希望 O_WRONLY | O_APPEND 是 0x9。
  • 好的,在转换一个使用 O_APPEND 的 C 程序并检查堆栈中的值后,我发现了 Mac OS X (MacOS) 的附加值......它是 $012(八进制)或 0x0a .
  • 是的,你是对的。 0x9 (O_WRONLY | O_APPEND) 也有效。我正在查看的 C 程序使用了 O_RDWR|O_APPEND,这意味着 2+8 或 0x0a。所以,0x09 或 0x0a 到 ECX 上面(而不是 0x0008)有效。感谢您帮助解决这个问题。

标签: macos file assembly append


【解决方案1】:

以下是用于在 mac os x (MacOS) 上附加文件的更正汇编语言代码版本(AT&T 风格)。

使用“as”和“ld”命令在 Mac 终端中编译“myfile.s”程序集文件:

as -m32 -o myfile.o myfile.s

ld -e _main -o myfile myfile.o

.data
filename:
.asciz "cpuid.txt"
output:
.asciz "The processor Vendor ID is 'xxxxxxxxxxxx'\n"

.bss
.lcomm filehandle, 4

.text
.globl _main
_main:
movl $0, %eax

# Get the CPUID and place the CPUID values (stored in ebx, edx and ecx) accordingly within,
# the correct address space, after the 'output' address.
cpuid
movl $output, %edi
movl %ebx, 28(%edi)
movl %edx, 32(%edi)
movl %ecx, 36(%edi)


# OPEN/CREATE A FILE:
movl $5, %eax
movl $filename, %ebx
movl $0x09, %ecx      # Access mode values loaded into ECX        
                      # on Linux, APPEND TEXT FILE using a $02002(octal) according to "Professional Assembly Language" (PAL) textbook
                      # however, on Mac OS X (MacOS), APPEND mode is 0x0008, according to usr/include/sys/fcntl.h
                      # ... so for write (0x01) and append (0x08) access (O_WRONLY | O_APPEND), the value becomes 0x09
                      # (for read/write (0x02) and append (0x08) access (O_RDWR|O_APPEND), the value would be 0x0a)

movl $0644, %edx      # file permission values loaded into EDX

# For MacOS, we need to put all of this on the stack (in reverse order),
# and, add an additional 4-bytes of space on the stack,
# prior to the system call (with 'int')
pushl %edx
pushl %ecx
pushl %ebx
subl  $4, %esp
int   $0x80             # ...make the system call
addl  $16, %esp         # clear the stack


test %eax, %eax         # check the error code returned (stored in EAX) after attempting to open/create the file
js badfile              # if the value was negative (i.e., an error occurred, then jump)
movl %eax, filehandle   # otherwise, move the error code to the 'filehandle'


# WRITE TO FILE:
movl $4, %eax
movl filehandle, %ebx
movl $output, %ecx
movl $42, %edx

# once again, for MacOS, put all of this on the stack,
# and, include an additional 4-bytes of space on the stack,
# (stack grows downward, thus the 'subl' instruction) prior to the 'int' system call
pushl %edx
pushl %ecx
pushl %ebx
subl $4, %esp
int $0x80
addl $16, %esp          # and, again, clear the stack

test %eax, %eax
js badfile



# CLOSE THE FILE:
movl $6, %eax
movl filehandle, %ebx

# okay, move it onto the stack again (only one parameter on stack for closing this time)
pushl %ebx
subl $4, %esp
int $0x80

addl $8, %esp

badfile:
subl $9, %esp
movl %eax, %ebx
movl $1, %eax
int $0x80

【讨论】:

  • 您可以#include <asm/unistd.h> 获取系统调用号常量,因此您可以执行mov $__NR_write, %eax 之类的操作。而不是将 args 放入 Linux ABI 的寄存器中,您应该直接推送,因为您使用的是 32 位 FreeBSD 系统调用 ABI。见stackoverflow.com/questions/2535989/…。 (更多链接请参见stackoverflow.com/tags/x86/info
  • 无论如何,您可以使用.equ 定义一些符号常量,或者使用gcc -dM 将您的sys/fcntl.h 中的宏定义转储到您可以从asm 中包含的标头中(不包含任何非 CPP C 定义)。然后你可以写push $0666/push $(O_WRONLY|O_APPEND)/push $filename。 (使用 0666 来获得让umask 完成工作的权限。)实际上,如果您的标志不包含O_CREAT,则永远不会使用该模式,但无论如何。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 2013-01-22
  • 2011-12-12
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 2014-01-22
相关资源
最近更新 更多