如何在汇编语言中找到奇数整数?

时间:2018-10-22 01:42:49

标签: assembly

编写一种汇编语言过程,以将两个整数乘以两倍和减半来相乘。这是使用这种方法将A和B相乘的伪代码。

Multiply A and B and store result in C:
C = 0 ; Initialize to 0
while B is not equal to 0:
if B is odd then C = C+A ; Add copy of A (even number left)
A = 2*A ; Can be done quickly by shifting left
B = B/2 ; Can be done quickly by shifting right

我已经做了大量的工作,我将如何使用shl测试奇数整数?

2 个答案:

答案 0 :(得分:1)

它可以使用'shr'指令;

mov al, 0x10010010b
shr al, 1      ;CF = 0   even

mov al, 0x10010011b
shr al, 1      ;CF = 1   odd

jnb __lable    ;jump if CF = 0
or
jb  __lable    ;jump if CF = 1

答案 1 :(得分:0)

对于x86_64,您可以同时使用shr进行奇数测试和零测试...

例如:

要在debugger中进行构建和测试,我使用了命令(在64b linux上):

nasm -f elf64 m.asm -l m.lst -w+all; ld -b elf64-x86-64 -o m m.o
edb --run ./m

来源:

    segment .text

mulByBits:
; input: 2x uint32_t in edi, esi (System V AMD64 ABI calling convention)
; output: uint64_t in rax
; modifies also: rcx
    xor     eax, eax            ; rax = 0 "C"
    mov     edi, edi            ; clear upper 32b of input "A" (extend to 64b)
.mulLoop:
    lea     rcx, [rax + rdi]    ; rcx = C + A (new C in case B is odd)
    add     rdi, rdi            ; A *= 2 (for next loop)
    shr     esi, 1              ; B >>= 1 (sets ZF and CF)
    cmovc   rax, rcx            ; if B was odd, update the sum to new C
    jnz     .mulLoop            ; repeat until B is zero
    ret

global _start
_start:     ; run some hardcoded simple tests, verify in debugger
    mov     edi, 143254         ; "normal" values test
    mov     esi, 43526
    call    mulByBits
    mov     rbx, 6235273604     ; expected result, compare with rax

    mov     edi, 0
    mov     esi, 0
    call    mulByBits
    mov     rbx, 0

    mov     edi, 43257432
    mov     esi, 0
    call    mulByBits
    mov     rbx, 0

    mov     edi, 0
    mov     esi, 432543
    call    mulByBits
    mov     rbx, 0

    mov     edi, 3276547234
    mov     esi, 1
    call    mulByBits
    mov     rbx, 3276547234

    mov     edi, 1
    mov     esi, 3276547234
    call    mulByBits
    mov     rbx, 3276547234

    mov     edi, ~0             ; UINT_MAX * UINT_MAX
    mov     esi, ~0
    call    mulByBits
    mov     rbx, 0xFFFFFFFE00000001

    mov     rdi, 0xE00000004    ; garbage in upper 32 bits of inputs
    mov     rsi, 0xE00000004    ; should be multiplied as 4*4
    call    mulByBits
    mov     rbx, 0x10

    ; exit back to linux
    mov     eax, 60
    xor     edi, edi
    syscall

加法是在大多数CPU上左移1的最有效方法。与add same,samehttps://agner.org/optimize)相比,shl rdi,1可以在更多的执行端口上运行,从而允许更多的指令级并行性,从而可能提高循环的吞吐量。