Translation

(itstool) path: sect2/para
I do, however, have to say that I tried to declare the <varname remap="structname">stat</varname> structure in the <varname>.bss</varname> section, and <function role="syscall">fstat</function> did not like it: It set the carry flag indicating an error. After I changed the code to allocate the structure on the stack, everything was working fine.
344/3470
Context English Persian State
The 32-bit Intel microprocessors can access up to four gigabytes of memory – physical or virtual. The FreeBSD system allows us to use up to a half of it for file mapping. ریزپردازنده‌های ۳۲ بیتی اینتل می‌توانند تا ۴ گیگابایت از حافظه دسترسی داشته باشند - فیزیکی یا مجازی. سامانهٔ FreeBSD به ما این امکان را می‌دهد تا نیمی از آن را برای نگاشت پرونده استفاده کنیم.
For simplicity sake, in this tutorial we will only convert files that can be mapped into the memory in their entirety. There are probably not too many text files that exceed two gigabytes in size. If our program encounters one, it will simply display a message suggesting we use the original <application>tuc</application> instead. به‌خاطر سادگی، ما در این آموزه تنها پرونده‌هایی را که به‌طور کامل می‌توانند در حافظه نگاشته شوند را تبدیل می‌کنیم. احتمالاً پرونده‌های متنی بسیاری وجود ندارند که اندازه‌شان از ۲ گیگابایت فراتر رود. اگر برنامهٔ ما با یکی از آنها برخورد کند، پیامی نمایش می‌دهد که پیشنهاد می‌دهد به جای آن از <application>tuc</application> اصلی استفاده کنیم.
If you examine your copy of <filename>syscalls.master</filename>, you will find two separate syscalls named <function role="syscall">mmap</function>. This is because of evolution of <trademark class="registered">UNIX</trademark>: There was the traditional <acronym>BSD</acronym> <function role="syscall">mmap</function>, syscall 71. That one was superseded by the <acronym><trademark class="registered">POSIX</trademark></acronym> <function role="syscall">mmap</function>, syscall 197. The FreeBSD system supports both because older programs were written by using the original <acronym>BSD</acronym> version. But new software uses the <acronym><trademark class="registered">POSIX</trademark></acronym> version, which is what we will use. اگر نسخهٔ خود از <filename>syscalls.master</filename> را بیازمایید، با دو فراخوان سامانهٔ جداگانه به نام <function role="syscall">mmap</function> مواجه می‌شوید. این به خاطر سیر تکاملی <trademark class="registered">UNIX</trademark> است: یک فراخوان سامانهٔ سنتی داشتیم، <acronym>BSD</acronym><function role="syscall">mmap</function> فراخون سامانهٔ 71. آن فراخوان توسط <acronym><trademark class="registered">POSIX</trademark></acronym><function role="syscall">mmap</function>، فراخوان سامانهٔ 197 جایگزین شد. سامانهٔ FreeBSD از هر دوی آنها پشتیبانی می‌کند زیرا برنامه‌های قدیمی به‌وسیلهٔ نسخهٔ اصلی <acronym>BSD</acronym> نگاشته شده‌اند. اما نرم‌افزار جدید از نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> استفاده می‌کند، که همان چیزیست که استفاده می‌کنیم.
The <filename>syscalls.master</filename> lists the <acronym><trademark class="registered">POSIX</trademark></acronym> version like this: <filename>syscalls.master</filename> نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> را بدین شکل فهرست می‌کند:
197 STD BSD { caddr_t mmap(caddr_t addr, size_t len, int prot, \
int flags, int fd, long pad, off_t pos); }
197 STD BSD { caddr_t mmap(caddr_t addr, size_t len, int prot, \
int flags, int fd, long pad, off_t pos); }
This differs slightly from what <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> says. That is because <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> describes the C version. این نسبت به آنچه که <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> می‌گوید تفاوت نسبی دارد. به این خاطر که <citerefentry><refentrytitle>mmap</refentrytitle><manvolnum>2</manvolnum></citerefentry> نسخهٔ C را توضیح می‌دهد.
The difference is in the <varname>long pad</varname> argument, which is not present in the C version. However, the FreeBSD syscalls add a 32-bit pad after <function role="opcode">push</function>ing a 64-bit argument. In this case, <varname>off_t</varname> is a 64-bit value. تفاوت در برهان <varname>long pad</varname> است، که در نسخهٔ C موجود نیست، فراخوان‌های سامانهٔ FreeBSD یک پَد ۳۲ بیتی بعد از <function role="opcode">push</function> کردن یک برهان ۶۴ بیتی اضافه می‌کنند. در این مورد، <varname>off_t</varname> یک مقدار ۶۴ بیتی است.
When we are finished working with a memory-mapped file, we unmap it with the <function role="syscall">munmap</function> syscall: هنگامی‌که کار ما با پروندهٔ memory-mapped تمام شد، نگاشت آن را با فراخوان سامانهٔ <function role="syscall">munmap</function> لغو می‌کنیم:
For an in-depth treatment of <function role="syscall">mmap</function>, see W. Richard Stevens' <link xlink:href="http://www.int80h.org/cgi-bin/isbn?isbn=0130810819">Unix Network Programming, Volume 2, Chapter 12</link>. برای مطالعهٔ عمیق <function role="syscall">mmap</function>، به <link xlink:href="http://www.int80h.org/cgi-bin/isbn?isbn=0130810819">Unix Network Programming, Volume 2, Chapter 12</link> از W. Richard Stevens مراجعه کنید.
Determining File Size تعیین اندازهٔ پرونده
Because we need to tell <function role="syscall">mmap</function> how many bytes of the file to map into the memory, and because we want to map the entire file, we need to determine the size of the file. از آنجا که باید تعداد بایت‌هایی که درون حافظه نگاشت می‌کنیم را به <function role="syscall">mmap</function> اعلام کنیم، و چون می‌خواهیم تمام پرونده را نگاشت کنیم، باید اندازهٔ پرونده را تعیین کنیم.
We can use the <function role="syscall">fstat</function> syscall to get all the information about an open file that the system can give us. That includes the file size. می‌توانیم از فراخوان سامانهٔ <function role="syscall">fstat</function> برای بدست آوردن تمام اطلاعات مربوط به پروندهٔ بازی که سامانه می‌تواند به ما بدهد استفاده کنیم. این اطلاعات شامل اندازهٔ پرونده می‌شود.
Again, <filename>syscalls.master</filename> lists two versions of <function role="syscall">fstat</function>, a traditional one (syscall 62), and a <acronym><trademark class="registered">POSIX</trademark></acronym> one (syscall 189). Naturally, we will use the <acronym><trademark class="registered">POSIX</trademark></acronym> version: دوباره، <filename>syscalls.master</filename> دو نسخه از <function role="syscall">fstat</function> را فهرست می‌کند، یک نسخهٔ سنتی (syscall 62)، و یک نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> (syscall 189). به‌طور طبیعی، از نسخهٔ <acronym><trademark class="registered">POSIX</trademark></acronym> استفاده می‌کنیم:
189 STD POSIX { int fstat(int fd, struct stat *sb); } 189 STD POSIX { int fstat(int fd, struct stat *sb); }
This is a very straightforward call: We pass to it the address of a <varname remap="structname">stat</varname> structure and the descriptor of an open file. It will fill out the contents of the <varname remap="structname">stat</varname> structure. این یک فراخوان بسیار مستقیم است: ما آن را به نشانی یک ساختمان <varname remap="structname">stat</varname> و یک توصیف‌گر پروندهٔ باز منتقل می‌کنیم. محتوای ساختمان <varname remap="structname">stat</varname> را پر می‌کند.
I do, however, have to say that I tried to declare the <varname remap="structname">stat</varname> structure in the <varname>.bss</varname> section, and <function role="syscall">fstat</function> did not like it: It set the carry flag indicating an error. After I changed the code to allocate the structure on the stack, everything was working fine. من، هرچند، لازم است خاطر نشان کنم که سعی کرده‌ام ساختمان <varname remap="structname">stat</varname> را در قسمت <varname>.bss</varname> تعریف کنم، و <function role="syscall">fstat</function> آن را دوست نداشت: نشان رقم نقلی‌ای را تعیین می‌کند که نشان‌گر خطاست . پس از آنکه کد را برای تخصیص ساختمان در پشته تغییر دادم، همه چیز به‌درستی کار می‌کرد.
Changing the File Size تغییر اندازهٔ پرونده
Because our program may combine carriage return / line feed sequences into straight line feeds, our output may be smaller than our input. However, since we are placing our output into the same file we read the input from, we may have to change the size of the file. از آنجا که برنامهٔ ما ممکن است توالی سرسطر / نوسطر را درون نوسطرهای مستقیم ترکیب ‌کند، ممکن است خروجی ما کوچک‌تر از ورودی‌مان باشد. گرچه، از آنجا که خروجی خود را در همان پرونده‌ای که ورودی را از آن می‌خوانیم قرار می‌دهیم، ممکن است مجبور به تغییر اندازهٔ پرونده باشیم.
The <function role="syscall">ftruncate</function> system call allows us to do just that. Despite its somewhat misleading name, the <function role="syscall">ftruncate</function> system call can be used to both truncate the file (make it smaller) and to grow it. فراخوان سامانهٔ <function role="syscall">ftruncate</function> این امکان را به ما می‌دهد تا دقیقاً همین کار را انجام دهیم. با وجود اسم نسبتاً‌ گمراه‌کننده‌اش، فراخوان سامانهٔ <function role="syscall">ftruncate</function> را می‌توان هم برای کوتاه کردن (کوچک‌تر کردن آن) و هم بزرگ کردن آن به کار برد.
And yes, we will find two versions of <function role="syscall">ftruncate</function> in <filename>syscalls.master</filename>, an older one (130), and a newer one (201). We will use the newer one: و بله، ما دو نسخه از <function role="syscall">ftruncate</function> را در <filename>syscalls.master</filename> پیدا خواهیم کرد، یک نسخهٔ‌ قدیمی‌تر (130) و نسخه‌ای جدیدتر (201). ما از نسخهٔ جدیدتر استفاده خواهیم کرد:
201 STD BSD { int ftruncate(int fd, int pad, off_t length); } 201 STD BSD { int ftruncate(int fd, int pad, off_t length); }
Please note that this one contains a <varname>int pad</varname> again. لطفاً توجه داشته باشید که این مورد دوباره شامل یک <varname>int pad</varname> است.
ftuc ftuc
We now know everything we need to write <application>ftuc</application>. We start by adding some new lines in <filename>system.inc</filename>. First, we define some constants and structures, somewhere at or near the beginning of the file: ما هر آنچه که برای نوشتن <application>ftuc</application> نیاز است را می‌دانیم. با اضافه کردن چندین خط جدید به <filename>system.inc</filename> آغاز می‌کنیم. ابتدا، چندین مقدار ثابت و ساختار را در جایی از ابتدای پرونده یا نزدیک آن تعریف می‌کنیم:
;;;;;;; open flags
%define O_RDONLY 0
%define O_WRONLY 1
%define O_RDWR 2

;;;;;;; mmap flags
%define PROT_NONE 0
%define PROT_READ 1
%define PROT_WRITE 2
%define PROT_EXEC 4
;;
%define MAP_SHARED 0001h
%define MAP_PRIVATE 0002h

;;;;;;; stat structure
struc stat
st_dev resd 1 ; = 0
st_ino resd 1 ; = 4
st_mode resw 1 ; = 8, size is 16 bits
st_nlink resw 1 ; = 10, ditto
st_uid resd 1 ; = 12
st_gid resd 1 ; = 16
st_rdev resd 1 ; = 20
st_atime resd 1 ; = 24
st_atimensec resd 1 ; = 28
st_mtime resd 1 ; = 32
st_mtimensec resd 1 ; = 36
st_ctime resd 1 ; = 40
st_ctimensec resd 1 ; = 44
st_size resd 2 ; = 48, size is 64 bits
st_blocks resd 2 ; = 56, ditto
st_blksize resd 1 ; = 64
st_flags resd 1 ; = 68
st_gen resd 1 ; = 72
st_lspare resd 1 ; = 76
st_qspare resd 4 ; = 80
endstruc
;;;;;;; open flags
%define O_RDONLY 0
%define O_WRONLY 1
%define O_RDWR 2

;;;;;;; mmap flags
%define PROT_NONE 0
%define PROT_READ 1
%define PROT_WRITE 2
%define PROT_EXEC 4
;;
%define MAP_SHARED 0001h
%define MAP_PRIVATE 0002h

;;;;;;; stat structure
struc stat
st_dev resd 1 ; = 0
st_ino resd 1 ; = 4
st_mode resw 1 ; = 8, size is 16 bits
st_nlink resw 1 ; = 10, ditto
st_uid resd 1 ; = 12
st_gid resd 1 ; = 16
st_rdev resd 1 ; = 20
st_atime resd 1 ; = 24
st_atimensec resd 1 ; = 28
st_mtime resd 1 ; = 32
st_mtimensec resd 1 ; = 36
st_ctime resd 1 ; = 40
st_ctimensec resd 1 ; = 44
st_size resd 2 ; = 48, size is 64 bits
st_blocks resd 2 ; = 56, ditto
st_blksize resd 1 ; = 64
st_flags resd 1 ; = 68
st_gen resd 1 ; = 72
st_lspare resd 1 ; = 76
st_qspare resd 4 ; = 80
endstruc
We define the new syscalls: فراخوان‌های سامانهٔ جدید را تعریف می‌کنیم:
%define SYS_mmap 197
%define SYS_munmap 73
%define SYS_fstat 189
%define SYS_ftruncate 201
%define SYS_mmap 197
%define SYS_munmap 73
%define SYS_fstat 189
%define SYS_ftruncate 201
We add the macros for their use: ماکروها را برای استفادهٔ آنها اضافه می‌کنیم:
%macro sys.mmap 0
system SYS_mmap
%endmacro

%macro sys.munmap 0
system SYS_munmap
%endmacro

%macro sys.ftruncate 0
system SYS_ftruncate
%endmacro

%macro sys.fstat 0
system SYS_fstat
%endmacro
%macro sys.mmap 0
system SYS_mmap
%endmacro

%macro sys.munmap 0
system SYS_munmap
%endmacro

%macro sys.ftruncate 0
system SYS_ftruncate
%endmacro

%macro sys.fstat 0
system SYS_fstat
%endmacro
And here is our code: و این کد ما هست:
;;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Started: 21-Dec-2000
;; Updated: 22-Dec-2000
;;
;; Copyright 2000 G. Adam Stanislav.
;; All rights reserved.
;;
;;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include 'system.inc'

section .data
db 'Copyright 2000 G. Adam Stanislav.', 0Ah
db 'All rights reserved.', 0Ah
usg db 'Usage: ftuc filename', 0Ah
usglen equ $-usg
co db "ftuc: Can't open file.", 0Ah
colen equ $-co
fae db 'ftuc: File access error.', 0Ah
faelen equ $-fae
ftl db 'ftuc: File too long, use regular tuc instead.', 0Ah
ftllen equ $-ftl
mae db 'ftuc: Memory allocation error.', 0Ah
maelen equ $-mae

section .text

align 4
memerr:
push dword maelen
push dword mae
jmp short error

align 4
toolong:
push dword ftllen
push dword ftl
jmp short error

align 4
facerr:
push dword faelen
push dword fae
jmp short error

align 4
cantopen:
push dword colen
push dword co
jmp short error

align 4
usage:
push dword usglen
push dword usg

error:
push dword stderr
sys.write

push dword 1
sys.exit

align 4
global _start
_start:
pop eax ; argc
pop eax ; program name
pop ecx ; file to convert
jecxz usage

pop eax
or eax, eax ; Too many arguments?
jne usage

; Open the file
push dword O_RDWR
push ecx
sys.open
jc cantopen

mov ebp, eax ; Save fd

sub esp, byte stat_size
mov ebx, esp

; Find file size
push ebx
push ebp ; fd
sys.fstat
jc facerr

mov edx, [ebx + st_size + 4]

; File is too long if EDX != 0 ...
or edx, edx
jne near toolong
mov ecx, [ebx + st_size]
; ... or if it is above 2 GB
or ecx, ecx
js near toolong

; Do nothing if the file is 0 bytes in size
jecxz .quit

; Map the entire file in memory
push edx
push edx ; starting at offset 0
push edx ; pad
push ebp ; fd
push dword MAP_SHARED
push dword PROT_READ | PROT_WRITE
push ecx ; entire file size
push edx ; let system decide on the address
sys.mmap
jc near memerr

mov edi, eax
mov esi, eax
push ecx ; for SYS_munmap
push edi

; Use EBX for state machine
mov ebx, ordinary
mov ah, 0Ah
cld

.loop:
lodsb
call ebx
loop .loop

cmp ebx, ordinary
je .filesize

; Output final lf
mov al, ah
stosb
inc edx

.filesize:
; truncate file to new size
push dword 0 ; high dword
push edx ; low dword
push eax ; pad
push ebp
sys.ftruncate

; close it (ebp still pushed)
sys.close

add esp, byte 16
sys.munmap

.quit:
push dword 0
sys.exit

align 4
ordinary:
cmp al, 0Dh
je .cr

cmp al, ah
je .lf

stosb
inc edx
ret

align 4
.cr:
mov ebx, cr
ret

align 4
.lf:
mov ebx, lf
ret

align 4
cr:
cmp al, 0Dh
je .cr

cmp al, ah
je .lf

xchg al, ah
stosb
inc edx

xchg al, ah
; fall through

.lf:
stosb
inc edx
mov ebx, ordinary
ret

align 4
.cr:
mov al, ah
stosb
inc edx
ret

align 4
lf:
cmp al, ah
je .lf

cmp al, 0Dh
je .cr

xchg al, ah
stosb
inc edx

xchg al, ah
stosb
inc edx
mov ebx, ordinary
ret

align 4
.cr:
mov ebx, ordinary
mov al, ah
; fall through

.lf:
stosb
inc edx
ret
;;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Started: 21-Dec-2000
;; Updated: 22-Dec-2000
;;
;; Copyright 2000 G. Adam Stanislav.
;; All rights reserved.
;;
;;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
%include 'system.inc'

section .data
db 'Copyright 2000 G. Adam Stanislav.', 0Ah
db 'All rights reserved.', 0Ah
usg db 'Usage: ftuc filename', 0Ah
usglen equ $-usg
co db "ftuc: Can't open file.", 0Ah
colen equ $-co
fae db 'ftuc: File access error.', 0Ah
faelen equ $-fae
ftl db 'ftuc: File too long, use regular tuc instead.', 0Ah
ftllen equ $-ftl
mae db 'ftuc: Memory allocation error.', 0Ah
maelen equ $-mae

section .text

align 4
memerr:
push dword maelen
push dword mae
jmp short error

align 4
toolong:
push dword ftllen
push dword ftl
jmp short error

align 4
facerr:
push dword faelen
push dword fae
jmp short error

align 4
cantopen:
push dword colen
push dword co
jmp short error

align 4
usage:
push dword usglen
push dword usg

error:
push dword stderr
sys.write

push dword 1
sys.exit

align 4
global _start
_start:
pop eax ; argc
pop eax ; program name
pop ecx ; file to convert
jecxz usage

pop eax
or eax, eax ; Too many arguments?
jne usage

; Open the file
push dword O_RDWR
push ecx
sys.open
jc cantopen

mov ebp, eax ; Save fd

sub esp, byte stat_size
mov ebx, esp

; Find file size
push ebx
push ebp ; fd
sys.fstat
jc facerr

mov edx, [ebx + st_size + 4]

; File is too long if EDX != 0 ...
or edx, edx
jne near toolong
mov ecx, [ebx + st_size]
; ... or if it is above 2 GB
or ecx, ecx
js near toolong

; Do nothing if the file is 0 bytes in size
jecxz .quit

; Map the entire file in memory
push edx
push edx ; starting at offset 0
push edx ; pad
push ebp ; fd
push dword MAP_SHARED
push dword PROT_READ | PROT_WRITE
push ecx ; entire file size
push edx ; let system decide on the address
sys.mmap
jc near memerr

mov edi, eax
mov esi, eax
push ecx ; for SYS_munmap
push edi

; Use EBX for state machine
mov ebx, ordinary
mov ah, 0Ah
cld

.loop:
lodsb
call ebx
loop .loop

cmp ebx, ordinary
je .filesize

; Output final lf
mov al, ah
stosb
inc edx

.filesize:
; truncate file to new size
push dword 0 ; high dword
push edx ; low dword
push eax ; pad
push ebp
sys.ftruncate

; close it (ebp still pushed)
sys.close

add esp, byte 16
sys.munmap

.quit:
push dword 0
sys.exit

align 4
ordinary:
cmp al, 0Dh
je .cr

cmp al, ah
je .lf

stosb
inc edx
ret

align 4
.cr:
mov ebx, cr
ret

align 4
.lf:
mov ebx, lf
ret

align 4
cr:
cmp al, 0Dh
je .cr

cmp al, ah
je .lf

xchg al, ah
stosb
inc edx

xchg al, ah
; fall through

.lf:
stosb
inc edx
mov ebx, ordinary
ret

align 4
.cr:
mov al, ah
stosb
inc edx
ret

align 4
lf:
cmp al, ah
je .lf

cmp al, 0Dh
je .cr

xchg al, ah
stosb
inc edx

xchg al, ah
stosb
inc edx
mov ebx, ordinary
ret

align 4
.cr:
mov ebx, ordinary
mov al, ah
; fall through

.lf:
stosb
inc edx
ret

Loading…

I do, however, have to say that I tried to declare the <varname remap="structname">stat</varname> structure in the <varname>.bss</varname> section, and <function role="syscall">fstat</function> did not like it: It set the carry flag indicating an error. After I changed the code to allocate the structure on the stack, everything was working fine.
من، هرچند، لازم است خاطر نشان کنم که سعی کرده‌ام ساختمان <varname remap="structname">stat</varname> را در قسمت <varname>.bss</varname> تعریف کنم، و <function role="syscall">fstat</function> آن را دوست نداشت: نشان رقم نقلی‌ای را تعیین می‌کند که نشان‌گر خطاست . پس از آنکه کد را برای تخصیص ساختمان در پشته تغییر دادم، همه چیز به‌درستی کار می‌کرد.
a month ago
I do, however, have to say that I tried to declare the <varname remap="structname">stat</varname> structure in the <varname>.bss</varname> section, and <function role="syscall">fstat</function> did not like it: It set the carry flag indicating an error. After I changed the code to allocate the structure on the stack, everything was working fine.
من، هرچند، لازم است خاطر نشان کنم که سعی کرده‌ام ساختمان <varname remap="structname">stat</varname> را در قسمت <varname>.bss</varname> تعریف کنم، و <function role="syscall">fstat</function> آن را دوست نداشت: نشان رقم نقلی‌ای را تعیین می‌کند که نشان‌گر خطاست . پس از آنکه کد را برای تخصیص ساختمان در پشته تغییر دادم، همه چیز به‌درستی کار کرد.
a month ago
Browse all component changes

Glossary

English Persian
Flag نشان FreeBSD Doc
Object code کد هدف FreeBSD Doc
Source Code کد منبع FreeBSD Doc
Stack پشته FreeBSD Doc

Source information

Source string comment
(itstool) path: sect2/para
Source string location
book.translate.xml:11695
String age
4 months ago
Source string age
a year ago
Translation file
books/fa/developers-handbook.po, string 1875