Recent Posts

Pages: 1 ... 8 9 [10]
91
Programming with NASM / Re: Multiply and store result in EAX
« Last post by Frank Kotler on January 13, 2021, 10:14:37 PM »
Hi mlk3ca,

It looks to me like you've got it figured out. You can use imul, but there''s nothing wrong  with mul.

There was, at one time, an instruction set reference in the Nasm manual. This is what's left if it:

http://home.myfairpoint.net/fbkotler/nasmdocr.html

It is badly outdated and still has a few errors. You should have seen it before Debs (and Yuri  and I) worked in it! For example, the description of "push" and "pop" were exactly the same! Debs is a "Nasm Developer" too, but in this case she's got it wrong. If you use a register. Nasm knows the size. I think using "word" with "ecx" would be an error. Try it. Don't be afraid to try stuff! You're doing great!

Best,
Frank

92
Example Code / Re: My own 64-bit `puts' instruction (No length required)
« Last post by Frank Kotler on January 13, 2021, 09:23:09 PM »
Looks as if you've reinvented "gets". No protection against overflow.  Take it away!

Best,
Frank

93
Programming with NASM / Re: Multiply and store result in EAX
« Last post by fredericopissarra on January 13, 2021, 06:26:33 PM »
You can use E?? registers in real mode. If your values are unsigned 16 bits values you can use 32 bits and IMUL instruction (the MSB will always be zero).

In the extreme case, multiplying 0xFFFF to 0xFFFF you'll get 0xFFFE0001, which will be an overflow if you get only the lower 16 bits, but this will happen with MUL as well.
94
Programming with NASM / Re: Multiply and store result in EAX
« Last post by mik3ca on January 13, 2021, 04:19:06 PM »
Code: [Select]
    mul EAX,word [ES:DI+itemoffset]or
Code: [Select]
    mov ECX,word [ES:DI+itemoffset]
    mul EAX,ECX

Unfortunately those won't work.

mul instruction don't give you the means to multiply ANY register, except EAX (or derivatives) by its operand... The result will always be in the pair EDX:EAX (or derivatives).
...

Code: [Select]
  mov eax,ecx
  mul [es:edi+offset]  ; 32 bits effective address.
  ; result is EDX:EAX = EAX * DWORD [ES:EDI+offset]

Ok, It turns out the best answer in my case is:

Code: [Select]
  mul  dword[es:edi+offset]  ; 32 bits effective address.

Thanks for the offer of imul but I don't want to reserve the MSB strictly for signing because that can also limit the values I can use. Like for example, If I had register AX as a signed register, then my positive values can only go from 0-7FFFh (0 - 32767) where as if it is unsigned, then my positive values can go from 0-FFFFh (0 - 65536)
95
Programming with NASM / Re: Multiply and store result in EAX
« Last post by fredericopissarra on January 13, 2021, 03:52:47 PM »
mul instruction don't give you the means to multiply ANY register, except EAX (or derivatives) by its operand... The result will always be in the pair EDX:EAX (or derivatives).

So, if you want to use mul to multiply ECX by the contents of memory (which, both must be the same size), you need to do:

Code: [Select]
  mov eax,ecx
  mul [es:edi+offset]  ; 32 bits effective address.
  ; result is EDX:EAX = EAX * DWORD [ES:EDI+offset]

There is a more flexible multiplication instruction: imul, which takes the signal of the operands in account. This instruction can be used as MUL (using EAX as default source operand and results in EDX:EAX) or when using 2 operands, multiply the source by the second operand and storing the result in the source... There is a third option: the first operand can be the result of the second operand multiplied by a CONSTANT as a third operand:
Code: [Select]
  imul ebx      ; EDX:EAX = EAX * EBX
  imul ebx,ecx ; EBX = EBX * ECX
  imul ebx,ecx,3 ; EBX = ECX * 3
But it is important to notice IMUL will consider the values as SIGNED.
96
Example Code / Re: My own 64-bit `puts' instruction (No length required)
« Last post by MediocreVeg1 on January 13, 2021, 07:47:26 AM »
UPDATE: I realised an issue with the procedure related to the way section .data works. From what I can tell, if you do this:
Code: [Select]
achar db "H"
bchar db "F"
the variables will be stored in the memory side-by-side with no space in-between, so no terminating character in-between. This means that if you print achar, it'll print bchar right after that. Due to this, I HIGHLY RECOMMEND YOU PUT THE NULL CHARACTER YOURSELF AT THE END OF EACH STRING. Apart from that, the rest is fine.
97
Example Code / My own 64-bit `puts' instruction (No length required)
« Last post by MediocreVeg1 on January 13, 2021, 06:32:21 AM »
So I've been having a bit of difficulty regarding procedures, and the people on this forum helped a lot (and helped me understand 64-bit assembly in general). So in return, I want to help others who may be having difficulty like me too with the `puts' procedure i made. But the main advantage of the procedure - not having to enter the length - requires another procedure `strlen', which calculates the length of the string (not including the terminating 0 character). It takes rdi (which should hold the string) as a parameter and returns the length in rax. So here it is:
Code: [Select]
strlen:
    xor rax, rax ; Return value, will count string length
    dec rdi
.cntloop:
    inc rax
    inc rdi
    cmp byte [rdi], 0 ; Terminating character
    jnz strlen.cntloop

    dec rax ; So that it does not include the last terminating character
    ret
Thanks to this, the actual printing procedure is really simple. It also takes rdi as a parameter and prints the string in the register:
Code: [Select]
puts:
    mov rsi, rdi
    call strlen
    mov rdx, rax
    mov rax, 1
    mov rdi, rax
    syscall
    ret

Note that the string doesn't need to have a 0 character at the end for this to work, but it would be better if you did put it.

This isn't as advanced as the `puts' macro I made, which didn't require the argument to be a variable and could take an infinite amount of arguments, but it couldn't print variables of .bss and too macros is probably a bad idea. Anyway, do give me any suggestions to improve the code if you feel it could be better.
98
Programming with NASM / Re: Multiply and store result in EAX
« Last post by debs3759 on January 13, 2021, 05:33:15 AM »
If using the contents of a memory address, you need to specify the operand size,  so, for example:

Code: [Select]
    mul EAX,word [ES:DI+itemoffset]
or

Code: [Select]
    mov ECX,word [ES:DI+itemoffset]
    mul EAX,ECX

(obviously, this can also be byte or dword)

nasm doesn't make assumptions about the operand size in most instructions.

I can't remember offhand whether you need to use EDI for the address when the destination is 32-bits. You may be OK, but hopefully Franf or Frederic can clarify that. It's been a while since I actually used nasm, so I'm a little rusty on some stuff.
99
Programming with NASM / Multiply and store result in EAX
« Last post by mik3ca on January 13, 2021, 05:16:08 AM »
This is probably simple for everyone but me, but I'm trying to multiply EAX by the contents of a memory location and storing the result in EAX using the following code fragments:

Code: [Select]
   
    mul EAX,[ES:DI+itemoffset]

Code: [Select]
    mov ECX,[ES:DI+itemoffset]
    mul EAX,ECX

but the compiler always complains on the multiply line with "invalid combination of opcode and operands"

How would I fix this? Do I remove the EAX in mul and assume the system knows that EAX is the other register to multiply with and store the result to?
100
Programming with NASM / Re: Segfaults in procedures and the stack
« Last post by MediocreVeg1 on January 13, 2021, 04:17:41 AM »
Ok. I also know that there are specific registers where arguments are passed now like rdi too, and rax is generally the return / error code register. The stack is proving to be a little problematic since I don't think I can push a string larger than 8 characters, so I might just use registers for params.
Pages: 1 ... 8 9 [10]