NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: mjrice on June 29, 2021, 03:34:52 AM
-
This function returns the highest character in the input qword that contains ABCDEFGH, printed in hex. The high word mask is hard coded in mhigh. How does one move the two dwords pointed to by EAX into mhigh and mlow?
mrice@debian10-uni:~$ ./test
ABCDEFGH
41
section .data
mhigh: dw 255
mlow: dw 0
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;eax <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
mov eax, [ecx]
mov edx, [ecx+4]
and eax, [mhigh]
and edx, [mlow]
ret
-
Why does ANY usage of register EBX, one of 4 general purpose registers, cause a seg-fault? Is there a way to temporarily unspecialize it for regular usage? In the code below it just replaces the EAX, pointer to the mask dwords, its only usage in the code, but still get a seg-fault. Why? B/t/w, checked out Gnu Fortran website but no 386 download was available.
global sqout_
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov ebx, [ebp+8] ;ebc <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
mov eax, [ecx]
mov edx, [ecx+4]
; and eax, [ebx]
; and edx, [ebx+4]
ret
-
x86 calling conventions (https://en.wikipedia.org/wiki/X86_calling_conventions)
-
So, EBX is off-limits. Thanks.
I was trying to print out the 8 character mask passed to my sqout function just to see if it jives with the input. If I can print it out I can also use it in an AND function. But seem to have a problem with one of the two dwords.
global sqout_
section .data
.mymask dd 0
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;eax <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
mov dword [.mymask], eax
mov eax, [.mymask]
mov edx, [eax+4]
ret
Is there a way around this problem in asm?
For CP(8) input:
mrice@debian10-uni:~$ ./test
ABCDEFGH
FF00000000472098
00472098 could be an address.
Just thought of another way to do it, a loop that increments the two pointers, ecx and eax, ANDing each pair.
AND byte [ECX], [EAX]
AND byte [ECX+1], [EAX+1]
...
-
Seems like I'm almost there. I'm asking for the 1st character CP(1) in "ABCDEFGH", and getting it (see I/O(CP(1)), 041h, but returning the high-order mask (which accurately matches the character retrieved), instead of what I expected in the low end, the result of
AND HGFE, 00000000h
which is 00000000h,
given that the the order of the characters in EAX and EDX is
EAX EDX
DCBA HGFE.
Masks are shown, in order, 1 to 8, in the fortran DATA statement, which matches the order of the characters in memory.
Ditto for the 2nd I/O(CP(4).
These outputs lack the right shifting, none for the 1st character, that would follow their retrieval.
Suggests welcome.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MAIN:
INTEGER CP(8),SQOUT
DATA CP /Z'00000000000000FF', Z'000000000000FF00',
1 Z'0000000000FF0000', Z'00000000FF000000',
2 Z'000000FF00000000', Z'0000FF0000000000',
3 Z'00FF000000000000', Z'FF00000000000000'/
100 FORMAT(A8)
110 FORMAT(Z16)
READ(*,100) IGET
IWORD=SQOUT(CP(1),IGET)
WRITE(*,110) IWORD
END
SQOUT:
global sqout_
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;eax <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
mov edx, [eax+4]
and [ecx+4], edx
mov edx, [ecx+4]
mov edx, [eax]
and [ecx], edx
mov eax, [ecx]
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I/O(CP(1):
mrice@debian10-uni:~$ ./test
ABCDEFGH
FF00000041
mrice@debian10-uni:~$
I/O(CP(4):
mrice@debian10-uni:~$ ./test
ABCDEFGH
FF00000044000000
mrice@debian10-uni:~$
-
Got it working. Wasn't saving EDX after using it for one job. Live and learn.
global sqout_
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;eax <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
mov edx, [eax+4]
and [ecx+4], edx
mov edx, [ecx+4]
push edx
mov edx, [eax]
and [ecx], edx
mov eax, [ecx]
pop edx
ret
-
Discovered that my 2nd arg, the 8 character qword was getting changed, bad for use in looping fortran code. Fixed it so both args remain unchanged.
ABCDEFGH ;2nd arg
0ffh ;1st arg
41 ;output, extracted letter
4847464544434241 ;2nd arg, after returning
FF ;1st arg, after returning
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
global sqout_
section .text ;AND 64-bit 2nd arg source with 1st arg mask
global sqout_
sqout_:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;eax <- addr of 1st arg, mask
mov ecx, [ebp+12] ;ecx <- addr of 2nd arg, source
pop ebp
; Isolate the character
push dword [ecx+4]
mov edx, [eax+4]
and [ecx+4], edx
mov edx, [ecx+4]
pop dword [ecx+4]
push edx
push dword [ecx]
mov edx, [eax]
and [ecx], edx
mov eax, [ecx]
pop dword [ecx]
pop edx
; Right-shift the character
mov ecx,edx
loop:
; cmp al, 32
cmp al, 0
jnz finished
shld edx,eax,8
shld eax,ecx,8
mov ecx, edx
jmp loop
finished:
ret