ASM Write to *Buffer

Bare metal programming in PureBasic, for experienced users
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

ASM Write to *Buffer

Post by nco2k »

a total asm-newbie question.

i need to copy some values to a buffer.

this (pseudocode) works:

Code: Select all

  Structure Buffer
    Buffer.b[12]
  EndStructure
  Protected Buffer.Buffer
  ...
  !MOV DWORD [p.v_Buffer], EAX
  !MOV DWORD [p.v_Buffer + 4], EBX
  !MOV DWORD [p.v_Buffer + 8], ECX
  ...
  Debug PeekL(@Buffer)
  Debug PeekL(@Buffer + 4)
  Debug PeekL(@Buffer + 8)
this (pseudocode) doesnt:

Code: Select all

  Protected *Buffer = AllocateMemory(12)
  ...
  !MOV DWORD [p.p_Buffer], EAX
  !MOV DWORD [p.p_Buffer + 4], EBX
  !MOV DWORD [p.p_Buffer + 8], ECX
  ...
  Debug PeekL(*Buffer)
  Debug PeekL(*Buffer + 4)
  Debug PeekL(*Buffer + 8)
can someone please explain what im doing wrong? :)

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
sys64802
Enthusiast
Enthusiast
Posts: 105
Joined: Sat Sep 12, 2015 6:55 pm

Re: ASM Write to *Buffer

Post by sys64802 »

Code: Select all

Procedure t()
 Protected *Buffer = AllocateMemory(12)
  
  !mov eax, [p.p_Buffer]
       
  !mov dword [eax], $ffffffff
  !mov dword [eax + 4], $fefefefe
  !mov dword [eax + 8], $fdfdfdfd 
  
  ShowMemoryViewer(*Buffer, 12)
  
EndProcedure 
  
t()
  

You are writing in memory starting ad the address of the pointer variable, not at the address stored inside the pointer.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: ASM Write to *Buffer

Post by nco2k »

cool thanks. :D

but i cant use eax, because eax-edx is filled with data that i need. is edi the right one in this case?

Code: Select all

Procedure t()
 Protected *Buffer = AllocateMemory(12)
  
  !mov edi, [p.p_Buffer]
  
  !mov eax, $ffffffff
  !mov ebx, $fefefefe
  !mov ecx, $fdfdfdfd
  
  !mov dword [edi], eax
  !mov dword [edi + 4], ebx
  !mov dword [edi + 8], ecx
  
  ShowMemoryViewer(*Buffer, 12)
  
EndProcedure

t()
c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
sys64802
Enthusiast
Enthusiast
Posts: 105
Joined: Sat Sep 12, 2015 6:55 pm

Re: ASM Write to *Buffer

Post by sys64802 »

According to the manual you can use eax, ecx and edx freely, but you need to preserve the others, so I think you should push edi (you can use the one you like, more or less) and then pop it before exit.

It should look this way:

Code: Select all

   
  !push edi
  
  !mov edi, [p.p_Buffer]
 
  !mov eax, $ffffffff
  !mov ebx, $fefefefe
  !mov ecx, $fdfdfdfd
 
  !mov dword [edi], eax
  !mov dword [edi + 4], ebx
  !mov dword [edi + 8], ecx
 
  !pop edi
  

but this doesn't work because by using push you alter the stack and PB defines the constant p.p_Buffer as an offset from the current stack pointer (esp).
So after your push you are reading a wrong value from a wrong place.

Code: Select all

; Procedure t()
_Procedure0:
  PS0=8
  XOR    eax,eax
  PUSH   eax
; Protected *Buffer = AllocateMemory(12)
  PUSH   dword 12
  CALL  _PB_AllocateMemory@4
  MOV    dword [esp],eax

p.p_Buffer equ esp+0 ; here it is, esp+0

push edi ; esp changed

mov edi, [p.p_Buffer] ; reading from the wrong place
; 

So you may do something like this:

Code: Select all

  !mov eax, [p.p_Buffer]
  
  !push edi
  
  !mov edi, eax
 
  !mov eax, $ffffffff
  !mov ebx, $fefefefe
  !mov ecx, $fdfdfdfd
 
  !mov dword [edi], eax
  !mov dword [edi + 4], ebx
  !mov dword [edi + 8], ecx
 
  !pop edi
  
Or even like this (but this is a little horrid and prone to errors)

Code: Select all


  !push edi
 
  !mov edi, [p.p_Buffer + 4] ; correct for the push
 
  !mov eax, $ffffffff
  !mov ebx, $fefefefe
  !mov ecx, $fdfdfdfd
 
  !mov dword [edi], eax
  !mov dword [edi + 4], ebx
  !mov dword [edi + 8], ecx
 
  !pop edi
  
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: ASM Write to *Buffer

Post by nco2k »

thanks a lot. very useful informations :)

c ya,
nco2k
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
User avatar
Keya
Addict
Addict
Posts: 1891
Joined: Thu Jun 04, 2015 7:10 am

Re: ASM Write to *Buffer

Post by Keya »

in this case it seems you dont need the stack and only need 2 registers if you do each value one-by-one rather than all-at-once? you'd probably have to use an approach more like this anyway if you had more data than the number of registers?

Code: Select all

! mov eax, [p.p_Buffer]
! mov ecx, $ffffffff
! mov dword [eax], ecx
! mov ecx, $fefefefe
! mov dword [eax+4], ecx
! mov ecx, $fdfdfdfd
! mov dword [eax+8], ecx
mines not a very good demo for learning anything about the stack though heehee (still learning here!)
Post Reply