Author Topic: Copying 4 bits from a register to 4 bits in a variable  (Read 7853 times)

Offline sandeepyadav

  • Jr. Member
  • *
  • Posts: 8
Copying 4 bits from a register to 4 bits in a variable
« on: August 27, 2013, 10:21:47 AM »
I am getting popped value which is of 4 bits into RAX register. I am carrying out pop 16 times, so I want to copy the 4 LSB bits of RAX register into 16 different nibbles of my variable(which is a quad word) i.e copy popped value from MSN(most significant nibble) of my variable to LSN. 

Regards,
Sandeep

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Copying 4 bits from a register to 4 bits in a variable
« Reply #1 on: August 27, 2013, 03:26:22 PM »
Keep in mind that I am not familiar with 64-bit code! I think I see the problem - we can only use a 32-bit immediate(?). Possibly something like this?

Code: [Select]
section .bss
var resq 1

section .text
;...
; 16 relevant qwords presumed on stack
;...

mov ebx, 0Fh
pop rax
shr rax, 60
; and rax, rbx ; useless?
or [var], rax

pop rax
shl rbx, 4
shr rax, 56
and rax, rbx
or [var], rax

pop rax
shl rbx, 4
shr rax, 52
and rax, rbx
or [var], rax

pop rax
shl rbx, 4
shr rax, 48
and rax, rbx
or [var], rax

pop rax
shl rbx, 4
shr rax, 44
and rax, rbx
or [var], rax

pop rax
shl rbx, 4
shr rax, 40
and rax, rbx
or [var], rax

pop rax
shl rbx, 4
shr rax, 36
and rax, rbx
or [var], rax

; etc...

pop rax
shl rbx, 4
; shr rax, 0
and rax, rbx
or [var], rax

That assembles without complaint. I have no idea if it actually works. I have no idea if it's what you have in mind. I have no idea what it would be useful for.

Best,
Frank


Offline sandeepyadav

  • Jr. Member
  • *
  • Posts: 8
Re: Copying 4 bits from a register to 4 bits in a variable
« Reply #2 on: August 27, 2013, 04:44:13 PM »

I was looking for the same thing. It should work for my code.

Thanks Frank.

Offline sandeepyadav

  • Jr. Member
  • *
  • Posts: 8
Re: Copying 4 bits from a register to 4 bits in a variable
« Reply #3 on: September 02, 2013, 03:20:27 PM »
 I have used the logic to convert Big endian number to little endian number. After debugging we can see reversed number. Whether, its correct approach for this conversion?
Code: [Select]
;conversion of 64 bit big endian number to little endian number

section .data
num    dq 123456789ABCDE0FH         
mask    dq 0000000000000000FH      
msg    db 'Big endian to Little endian successful',10
msgLen: equ $-msg 

section .text
global _start

_start: mov ecx, 16
mov rbx,[num]
up: mov esi, num
rol rbx,4
mov rax, rbx
and rax, [mask]
push (rax)                  ;;;;pushing only nibble
loop up
mov edx,16
and qword[num], 0000000000000000H        ;;;making number zero
mov rsi,num
mov cl, 60
up1: pop (rax)
rol rax, cl
sub cl,4
or qword[rsi],rax             ;;;for inserting popped value at intended place
dec edx
jnz up1

; to display ASCII value conversion is left
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msgLen
syscall

exit: mov rax,60
xor rdi,rdi
syscall

 Regards,
 Sandeep

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Copying 4 bits from a register to 4 bits in a variable
« Reply #4 on: September 03, 2013, 06:56:17 AM »
At first, I read your "push (rax)" and "pop (rax)" as "push [rax]" and "pop [rax]" which would not have been right. I guess it's okay. Does it work? For 32-bit code, there's "bswap". I don't know if there's a 64-bit version or not. I'm guessing that there might be.

Best,
Frank


Offline sandeepyadav

  • Jr. Member
  • *
  • Posts: 8
Re: Copying 4 bits from a register to 4 bits in a variable
« Reply #5 on: September 03, 2013, 02:39:38 PM »
Yes, this code works. But I was working on nibble. I have modified it to work on byte. Will try with bswap if available.
Code: [Select]
;conversion of 64 bit big endian number to little endian number

section .data
num    dq 123456789ABCDE0FH         
mask    dq 000000000000000FFH      
msg    db 'Big endian to Little endian successful',10
msgLen: equ $-msg 

section .text
global _start

_start:
        mov ecx, 8         ;;;;;;count of digits
mov rbx,[num] ;;;;;;moving number in rbx for processing
up: rol rbx,8         ;;;;;;rotation for pushing byte
mov rax, rbx ;;;;;;keeping rbx as it is
and rax, [mask] ;;;;;;masking to separate byte
push (rax)
loop up
mov edx,8         ;;;;;;tracking how many times to pop
and qword[num], 0000000000000000H   ;;;;;;;;;making num = 0 i.e. 8 bytes set to 0
mov rsi,num
mov cl, 56 ;;;;;;count of rotation
up1: pop (rax)
rol rax, cl
sub cl,8     ;;;;;;reducing rotation count by 8
or qword[rsi],rax     ;;;;;;placing popped value at intended location
dec edx
jnz up1

; to display ASCII value conversion is left
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msgLen
syscall

exit: mov rax,60
xor rdi,rdi
syscall

Regards,
Sandeep