NTFS: more files in folders

git-svn-id: svn://kolibrios.org@6292 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
pathoswithin 2016-02-25 17:10:35 +00:00
parent 2a32370a8a
commit ac3100f5b1

View File

@ -121,6 +121,7 @@ LastRead dd ? ; last readen block of sectors
newMftRecord dd ? ; number of fileRecord in MFT newMftRecord dd ? ; number of fileRecord in MFT
fileDataStart dd ? ; starting cluster fileDataStart dd ? ; starting cluster
fileDataSize dd ? ; in clusters fileDataSize dd ? ; in clusters
fileDataBuffer dd ?
fileRealSize dd ? ; in bytes fileRealSize dd ? ; in bytes
indexOffset dd ? indexOffset dd ?
nodeLastRead dd ? nodeLastRead dd ?
@ -2093,18 +2094,19 @@ ntfs_CreateFile:
mov edi, [ebp+NTFS.cur_index_buf] mov edi, [ebp+NTFS.cur_index_buf]
push esi push esi
push ecx push ecx
mov edx, [ebx+12]
mov [ebp+NTFS.fileRealSize], edx
mov edx, [ebx+16]
mov [ebp+NTFS.fileDataBuffer], edx
mov edx, ecx
cmp dword [edi], 'INDX' cmp dword [edi], 'INDX'
jz .indexRecord jz .indexRecord
mov esi, [ebp+NTFS.frs_buffer] ; indexRoot mov esi, [ebp+NTFS.frs_buffer] ; indexRoot
mov edx, [esi+recordRealSize] mov ecx, [esi+recordRealSize]
add edx, ecx add edx, ecx
cmp [esi+recordAllocatedSize], edx cmp [esi+recordAllocatedSize], edx
jnc @f jc .growTree
add esp, 12
jmp ntfsUnsupported ; indexAllocation required
@@: ; index fits in the indexRoot
mov [esi+recordRealSize], edx mov [esi+recordRealSize], edx
mov ecx, edx
shr ecx, 2 shr ecx, 2
rep movsd rep movsd
mov edi, [ebp+NTFS.attr_offs] mov edi, [ebp+NTFS.attr_offs]
@ -2120,27 +2122,167 @@ ntfs_CreateFile:
sub eax, [ebp+NTFS.cur_index_buf] sub eax, [ebp+NTFS.cur_index_buf]
add eax, edi add eax, edi
mov edi, [ebp+NTFS.cur_index_buf] mov edi, [ebp+NTFS.cur_index_buf]
add edi, edx
sub edi, 4
jmp .common jmp .common
@@:
add esp, 16
jmp ntfsUnsupported
.growTree:
sub eax, rootNode
sub eax, [edi+rootNode+indexOffset]
push eax
; create indexRecord
mov ecx, 10
xor eax, eax
rep stosd
rdtsc
stosw
mov esi, [ebp+NTFS.attr_offs]
mov cl, [esi+attributeOffset]
add esi, ecx
mov eax, [esi+indexRecordSizeClus]
cmp eax, 128
jnc @b
mov [ebp+NTFS.fileDataSize], eax
mov eax, [esi+indexRecordSize]
cmp eax, [ebp+NTFS.frs_size]
jc @b
shr eax, 9
inc eax
mov edi, [ebp+NTFS.cur_index_buf]
mov dword[edi], 'INDX'
mov byte [edi+updateSequenceOffset], 28h
mov [edi+updateSequenceSize], al
add edi, recordNode
shl eax, 1
add eax, 28h-recordNode+7
and eax, not 7
mov [edi+indexOffset], eax
mov ecx, [esi+indexRecordSize]
sub ecx, recordNode
mov [edi+nodeAllocatedSize], ecx
add esi, rootNode
push esi
mov ecx, [esi+nodeRealSize]
sub ecx, [esi+indexOffset]
add eax, ecx
mov [edi+nodeRealSize], eax
shr ecx, 2
add esi, [esi+indexOffset]
add edi, [edi+indexOffset]
rep movsd ; copy root indexes
; clear root node
mov cl, 10
mov edi, [esp]
xor eax, eax
rep stosd
pop edi
mov byte [edi+indexOffset], 16
mov byte [edi+nodeRealSize], 28h
mov byte [edi+nodeAllocatedSize], 28h
mov byte [edi+nonLeafFlag], 1
mov byte [edi+16+indexAllocatedSize], 18h
mov byte [edi+16+indexFlags], 3
mov esi, [ebp+NTFS.attr_offs]
add edi, 28h
mov eax, edi
sub eax, esi
mov word [esi+sizeWithoutHeader], 38h
xchg [esi+sizeWithHeader], eax
cmp byte [esi+eax], -1
jnz @b
mov cl, 32
xor eax, eax
push edi
rep stosd
mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc
jnc @f
add esp, 20
jmp ntfsDiskFull
@@: ; create $IndexAllocation
pop edi
mov byte [edi+attributeType], 0xA0
mov byte [edi+nonResidentFlag], 1
mov byte [edi+nameLength], 4
mov byte [edi+nameOffset], 40h
mov byte [edi+dataRunsOffset], 48h
mov byte [edi+sizeWithHeader], 50h
mov eax, [ebp+NTFS.fileDataSize]
dec eax
mov [edi+lastVCN], eax
inc eax
mul [ebp+NTFS.sectors_per_cluster]
shl eax, 9
mov [edi+attributeAllocatedSize], eax
mov [edi+attributeRealSize], eax
mov [edi+initialDataSize], eax
mov dword[edi+40h], 490024h ; unicode $I30
mov dword[edi+40h+4], 300033h
push edi
mov esi, edi
add edi, 48h
call createMcbEntry
mov esi, [ebp+NTFS.frs_buffer]
pop edi
mov al, [esi+newAttributeID]
mov [edi+attributeID], al
add edi, 50h
inc eax
; create $Bitmap
mov [edi+attributeID], al
inc eax
mov [esi+newAttributeID], al
mov byte [edi+attributeType], 0xB0
mov byte [edi+nameLength], 4
mov byte [edi+nameOffset], 18h
mov byte [edi+attributeOffset], 20h
mov byte [edi+sizeWithoutHeader], 8
mov byte [edi+sizeWithHeader], 28h
mov dword[edi+18h], 490024h ; unicode $I30
mov dword[edi+18h+4], 300033h
mov byte [edi+20h], 1
mov dword[edi+28h], -1
add edi, 30h
sub edi, esi
mov [esi+recordRealSize], edi
mov [ebp+NTFS.cur_buf], esi
call writeRecord ; fileRecord
mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster]
mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf]
mov [ebp+NTFS.cur_buf], eax
call writeRecord ; indexRecord
mov ebx, [ebp+NTFS.cur_index_buf]
mov ax, [ebx+6]
dec eax
shl eax, 9
call ntfs_restore_usa
mov edi, [ebp+NTFS.cur_index_buf]
pop eax
add eax, recordNode
add eax, [edi+recordNode+indexOffset]
mov edx, [esp]
.indexRecord: .indexRecord:
add edi, recordNode add edi, recordNode
mov edx, [edi+nodeRealSize] add edx, [edi+nodeRealSize]
add edx, ecx
cmp [edi+nodeAllocatedSize], edx cmp [edi+nodeAllocatedSize], edx
jnc @f jnc @f
add esp, 12 add esp, 12
jmp ntfsUnsupported ; new node required jmp ntfsUnsupported ; new node required
@@: ; index fits in the node @@: ; index fits in the node
mov [edi+nodeRealSize], edx mov [edi+nodeRealSize], edx
.common:
add edi, edx add edi, edx
sub edi, 4 sub edi, 4
.common:
mov esi, edi mov esi, edi
sub esi, [esp] sub esi, [esp]
mov ecx, esi mov ecx, esi
sub ecx, eax ; eax = pointer in the node sub ecx, eax ; eax = pointer in the record
shr ecx, 2 shr ecx, 2
inc ecx inc ecx
std std
@ -2163,15 +2305,15 @@ ntfs_CreateFile:
mov eax, [ebp+NTFS.frs_buffer] mov eax, [ebp+NTFS.frs_buffer]
mov eax, [eax+reuseCounter] mov eax, [eax+reuseCounter]
mov [edi+directoryReferenceReuse], ax mov [edi+directoryReferenceReuse], ax
mov eax, [ebx+12] mov eax, [ebp+NTFS.frs_size]
shr eax, 8
add ecx, 30h+48h+8+18h+8 add ecx, 30h+48h+8+18h+8
add ecx, eax add ecx, eax
mov [ebp+NTFS.fileRealSize], eax mov eax, [ebp+NTFS.fileRealSize]
add ecx, eax
mov [edi+fileRealSize], eax mov [edi+fileRealSize], eax
cmp [ebp+NTFS.frs_size], ecx cmp [ebp+NTFS.frs_size], ecx
jc @f jc @f
mov eax, [ebx+16]
mov [ebp+NTFS.fileDataStart], eax
xor eax, eax xor eax, eax
@@: @@:
mov ecx, [ebp+NTFS.sectors_per_cluster] mov ecx, [ebp+NTFS.sectors_per_cluster]
@ -2207,12 +2349,12 @@ ntfs_CreateFile:
mov edi, [ebp+NTFS.BitmapStart] mov edi, [ebp+NTFS.BitmapStart]
call ntfsSpaceAlloc call ntfsSpaceAlloc
jc ntfsDiskFull jc ntfsDiskFull
mov [ebp+NTFS.fileDataStart], eax mov eax, [ebp+NTFS.fileDataStart]
mul [ebp+NTFS.sectors_per_cluster] mul [ebp+NTFS.sectors_per_cluster]
mov ecx, [ebp+NTFS.fileRealSize] mov ecx, [ebp+NTFS.fileRealSize]
add ecx, 511 add ecx, 511
shr ecx, 9 shr ecx, 9
mov ebx, [ebx+16] mov ebx, [ebp+NTFS.fileDataBuffer]
call fs_write64_app call fs_write64_app
test eax, eax test eax, eax
jnz ntfsDevice jnz ntfsDevice
@ -2315,19 +2457,22 @@ ntfs_CreateFile:
rep stosd rep stosd
mov edi, [ebp+NTFS.frs_buffer] mov edi, [ebp+NTFS.frs_buffer]
; record header ; record header
rdtsc
mov [edi+2ah], ax
mov eax, [ebp+NTFS.frs_size] mov eax, [ebp+NTFS.frs_size]
mov [edi+recordAllocatedSize], eax mov [edi+recordAllocatedSize], eax
shr eax, 9 shr eax, 9
inc eax inc eax
mov [edi+updateSequenceSize], al mov [edi+updateSequenceSize], al
shl eax, 1
add eax, 2ah+7
and eax, not 7
mov dword[edi], 'FILE' mov dword[edi], 'FILE'
mov byte [edi+updateSequenceOffset], 2ah mov byte [edi+updateSequenceOffset], 2ah
mov byte [edi+hardLinkCounter], 1 mov byte [edi+hardLinkCounter], 1
mov byte [edi+attributeOffset], 30h
mov byte [edi+newAttributeID], 3 mov byte [edi+newAttributeID], 3
rdtsc mov [edi+attributeOffset], al
mov [edi+2ah], ax add edi, eax
add edi, 30h
; $StandardInformation ; $StandardInformation
mov byte [edi+attributeType], 10h mov byte [edi+attributeType], 10h
mov byte [edi+sizeWithHeader], 48h mov byte [edi+sizeWithHeader], 48h
@ -2381,7 +2526,7 @@ ntfs_CreateFile:
mov [edi+sizeWithoutHeader], ecx mov [edi+sizeWithoutHeader], ecx
mov byte [edi+attributeOffset], 18h mov byte [edi+attributeOffset], 18h
push edi push edi
mov esi, [ebp+NTFS.fileDataStart] mov esi, [ebp+NTFS.fileDataBuffer]
add edi, 18h add edi, 18h
rep movsb rep movsb
@@: @@:
@ -2393,7 +2538,7 @@ ntfs_CreateFile:
mov [edi+sizeWithHeader], eax mov [edi+sizeWithHeader], eax
add edi, eax add edi, eax
mov al, 1 mov al, 1
jmp @f jmp .end
.indexRoot: .indexRoot:
mov byte [edi+attributeType], 90h mov byte [edi+attributeType], 90h
@ -2406,9 +2551,16 @@ ntfs_CreateFile:
mov byte [edi+20h+indexedAttributesType], 30h mov byte [edi+20h+indexedAttributesType], 30h
mov byte [edi+20h+collationRule], 1 mov byte [edi+20h+collationRule], 1
mov eax, [ebp+NTFS.sectors_per_cluster] mov eax, [ebp+NTFS.sectors_per_cluster]
shl eax, 9 mov dl, 1
shl eax, 8
@@:
shl eax, 1
shl edx, 1
cmp eax, [ebp+NTFS.frs_size]
jc @b
shr edx, 1
mov [edi+20h+indexRecordSize], eax mov [edi+20h+indexRecordSize], eax
mov byte [edi+20h+indexRecordSizeClus], 1 mov [edi+20h+indexRecordSizeClus], dl
mov byte [edi+30h+indexOffset], 16 mov byte [edi+30h+indexOffset], 16
mov byte [edi+30h+nodeRealSize], 32 mov byte [edi+30h+nodeRealSize], 32
mov byte [edi+30h+nodeAllocatedSize], 32 mov byte [edi+30h+nodeAllocatedSize], 32
@ -2416,7 +2568,7 @@ ntfs_CreateFile:
mov byte [edi+40h+indexFlags], 2 mov byte [edi+40h+indexFlags], 2
add edi, 50h add edi, 50h
mov al, 3 mov al, 3
@@: .end:
mov esi, [ebp+NTFS.frs_buffer] mov esi, [ebp+NTFS.frs_buffer]
mov dword [edi], -1 mov dword [edi], -1
mov dword [edi+4], 0 mov dword [edi+4], 0
@ -2426,8 +2578,6 @@ ntfs_CreateFile:
mov [esi+recordFlags], al mov [esi+recordFlags], al
mov [esi+recordRealSize], edi mov [esi+recordRealSize], edi
call writeRecord call writeRecord
test eax, eax
jnz ntfsDevice
; write MFT bitmap ; write MFT bitmap
mov eax, [ebp+NTFS.newMftRecord] mov eax, [ebp+NTFS.newMftRecord]
shr eax, 3+9 shr eax, 3+9
@ -2438,33 +2588,10 @@ ntfs_CreateFile:
mov ecx, 1 mov ecx, 1
xor edx, edx xor edx, edx
call fs_write64_sys call fs_write64_sys
test eax, eax
jnz ntfsDevice
; 5. Write partition bitmap
cmp [ebp+NTFS.bFolder], 1
jz @f
mov eax, [ebp+NTFS.fileDataStart]
mov ecx, [ebp+NTFS.fileDataSize]
test ecx, ecx
jz @f
add ecx, eax
add ecx, 4095
shr ecx, 3+9
shr eax, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
call fs_write64_app
test eax, eax
jnz ntfsDevice
@@:
mov edi, [ebp+NTFS.indexOffset] mov edi, [ebp+NTFS.indexOffset]
mov eax, [ebp+NTFS.newMftRecord] mov eax, [ebp+NTFS.newMftRecord]
mov [edi+fileRecordReference], eax mov [edi+fileRecordReference], eax
; 6. Write directory node ; 5. Write directory node
mov eax, [ebp+NTFS.nodeLastRead] mov eax, [ebp+NTFS.nodeLastRead]
mov [ebp+NTFS.LastRead], eax mov [ebp+NTFS.LastRead], eax
mov eax, [ebp+NTFS.cur_index_buf] mov eax, [ebp+NTFS.cur_index_buf]
@ -2626,6 +2753,7 @@ resizeAttribute:
@@: @@:
call ntfsSpaceAlloc call ntfsSpaceAlloc
jc .err1 jc .err1
mov eax, [ebp+NTFS.fileDataStart]
pop edi pop edi
pop edx pop edx
cmp edx, eax cmp edx, eax
@ -2648,44 +2776,23 @@ resizeAttribute:
@@: @@:
mov esi, [ebp+NTFS.attr_offs] mov esi, [ebp+NTFS.attr_offs]
call createMcbEntry call createMcbEntry
pop ecx pop [ebp+NTFS.fileDataSize]
pop eax pop [ebp+NTFS.fileDataStart]
jc .err2 movi eax, ERROR_UNSUPPORTED_FS
mov [ebp+NTFS.fileDataSize], ecx
mov [ebp+NTFS.fileDataStart], eax
.writeBitmap:
add ecx, eax
add ecx, 4095
shr ecx, 3+9
shr eax, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
call fs_write64_app
test eax, eax
jnz @f
.done: .done:
ret ret
.err4:
pop eax
@@:
movi eax, ERROR_DEVICE
stc
ret
.err1: .err1:
add esp, 24 add esp, 24
stc stc
.err10: .err2:
movi eax, ERROR_DISK_FULL movi eax, ERROR_DISK_FULL
ret ret
.err2: .err3:
movi eax, ERROR_UNSUPPORTED_FS movi eax, ERROR_FS_FAIL
add esp, 20
stc
ret ret
.shrinkAttribute: .shrinkAttribute:
@ -2732,12 +2839,6 @@ resizeAttribute:
@@: @@:
ret ret
.err3:
movi eax, ERROR_FS_FAIL
add esp, 20
stc
ret
.resident: .resident:
test edx, edx test edx, edx
jnz .nonResident jnz .nonResident
@ -2791,8 +2892,7 @@ resizeAttribute:
push ecx push ecx
call ntfsSpaceAlloc call ntfsSpaceAlloc
pop ecx pop ecx
jc .err10 jc .err2
mov [ebp+NTFS.fileDataStart], eax
mov esi, [ebp+NTFS.attr_offs] mov esi, [ebp+NTFS.attr_offs]
xor eax, eax xor eax, eax
xor edx, edx xor edx, edx
@ -2820,11 +2920,7 @@ resizeAttribute:
pop ecx pop ecx
shr ecx, 9 shr ecx, 9
call fs_write64_app call fs_write64_app
push ebx stdcall kernel_free, ebx
mov ebx, eax
call kernel_free
test ebx, ebx
jnz .err4
mov esi, [ebp+NTFS.attr_offs] mov esi, [ebp+NTFS.attr_offs]
add esi, [esi+sizeWithHeader] add esi, [esi+sizeWithHeader]
mov ecx, [ebp+NTFS.frs_buffer] mov ecx, [ebp+NTFS.frs_buffer]
@ -2875,11 +2971,9 @@ resizeAttribute:
sub edi, esi sub edi, esi
mov [esi+recordRealSize], edi mov [esi+recordRealSize], edi
pop edx pop edx
mov ecx, [ebp+NTFS.fileDataSize]
sub [ebp+NTFS.fileDataSize], edx sub [ebp+NTFS.fileDataSize], edx
mov eax, [ebp+NTFS.fileDataStart]
add [ebp+NTFS.fileDataStart], edx add [ebp+NTFS.fileDataStart], edx
jmp .writeBitmap ret
.makeResident: ; convert non-resident to empty resident .makeResident: ; convert non-resident to empty resident
movzx eax, byte [esi+dataRunsOffset] movzx eax, byte [esi+dataRunsOffset]
@ -2936,13 +3030,14 @@ ntfsSpaceClean:
ret ret
ntfsSpaceAlloc: ntfsSpaceAlloc:
; find and mark block of free space in bitmap buffer ; allocate disk space
; in: ; in:
; edi = offset in bitmap to start search from ; edi = offset in bitmap to start search from
; [ebp+NTFS.fileDataSize] = block size in clusters ; [ebp+NTFS.fileDataSize] = block size in clusters
; out: ; out:
; eax = allocated block starting cluster ; [ebp+NTFS.fileDataStart] = allocated block starting cluster
; CF=1 -> disk full ; CF=1 -> disk full
push eax
mov ecx, [ebp+NTFS.BitmapBuffer] mov ecx, [ebp+NTFS.BitmapBuffer]
add edi, ecx add edi, ecx
add ecx, [ebp+NTFS.BitmapSize] add ecx, [ebp+NTFS.BitmapSize]
@ -2955,7 +3050,7 @@ ntfsSpaceAlloc:
mov eax, [ebp+NTFS.fileDataSize] mov eax, [ebp+NTFS.fileDataSize]
shr eax, 5 shr eax, 5
jz .small jz .small
push eax ; bitmap dwords mov ebx, eax ; bitmap dwords
.start: .start:
mov ecx, [ebp+NTFS.BitmapBuffer] mov ecx, [ebp+NTFS.BitmapBuffer]
add ecx, [ebp+NTFS.BitmapSize] add ecx, [ebp+NTFS.BitmapSize]
@ -2968,13 +3063,13 @@ ntfsSpaceAlloc:
call bitmapBuffering call bitmapBuffering
jmp @b jmp @b
@@: @@:
cmp ecx, [esp] cmp ecx, ebx
jnc @f jnc @f
call bitmapBuffering call bitmapBuffering
jmp @b jmp @b
@@: @@:
sub edi, 4 sub edi, 4
mov ecx, [esp] mov ecx, ebx
mov esi, edi mov esi, edi
xor eax, eax xor eax, eax
repz scasd ; check following dwords repz scasd ; check following dwords
@ -3007,28 +3102,26 @@ ntfsSpaceAlloc:
.small: ; less than 32 clusters .small: ; less than 32 clusters
mov eax, -1 mov eax, -1
repz scasd ; search for zero bits repz scasd ; search for zero bits
push ecx
test ecx, ecx test ecx, ecx
jnz @f jnz @f
call bitmapBuffering call bitmapBuffering
pop eax
jmp .small jmp .small
@@: @@:
sub edi, 4 sub edi, 4
mov eax, [edi] mov eax, [edi]
not eax not eax
@@: @@:
bsf ecx, eax ; first 0 bsf ebx, eax ; first 0
jz .again jz .again
not eax not eax
shr eax, cl shr eax, cl
shl eax, cl shl eax, cl
bsf edx, eax ; next 1 bsf edx, eax ; next 1
jz @f jz @f
sub edx, ecx sub edx, ebx
cmp edx, [ebp+NTFS.fileDataSize] cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; fits inside jnc .got ; fits inside
bsf ecx, eax bsf ebx, eax
not eax not eax
shr eax, cl shr eax, cl
shl eax, cl shl eax, cl
@ -3038,16 +3131,15 @@ ntfsSpaceAlloc:
bsf edx, eax bsf edx, eax
jz .got ; empty jz .got ; empty
add edx, 32 add edx, 32
sub edx, ecx sub edx, ebx
cmp edx, [ebp+NTFS.fileDataSize] cmp edx, [ebp+NTFS.fileDataSize]
jnc .got ; share between dwords jnc .got ; share between dwords
.again: .again:
add edi, 4 add edi, 4
pop ecx
jmp .small jmp .small
.got: .got:
push ecx ; starting bit push ebx ; starting bit
push edi ; starting dword push edi ; starting dword
.done: ; mark space .done: ; mark space
mov ecx, [esp+4] mov ecx, [esp+4]
@ -3088,12 +3180,24 @@ ntfsSpaceAlloc:
or [edi], eax or [edi], eax
.end: .end:
pop eax pop eax
pop ecx
sub eax, [ebp+NTFS.BitmapBuffer] sub eax, [ebp+NTFS.BitmapBuffer]
shl eax, 3 shl eax, 3
pop edx add eax, ecx
add eax, edx pop ecx
pop edx mov ecx, [ebp+NTFS.fileDataSize]
ret mov [ebp+NTFS.fileDataStart], eax
add ecx, eax
add ecx, 4095
shr ecx, 3+9
shr eax, 3+9
sub ecx, eax
mov ebx, eax
shl ebx, 9
add eax, [ebp+NTFS.BitmapLocation]
add ebx, [ebp+NTFS.BitmapBuffer]
xor edx, edx
jmp fs_write64_app
ntfsSpaceFree: ntfsSpaceFree:
; free disk space ; free disk space
@ -3208,9 +3312,7 @@ bitmapBuffering:
mov ecx, 8 mov ecx, 8
call release_pages call release_pages
.end: .end:
pop ebx add esp, 12 ; ret
pop eax ; ret
pop eax
stc stc
ret ret