You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在x86 MASM汇编中从文件随机选取8个单词的实现方法

How to Select 8 Random Words from a Text File in x86 MASM

Great to see you've already nailed the file reading and console display basics! Let's build on that code to pick 8 unique random words from your 500-word list. Here's a step-by-step breakdown of how to make this work:

Step 1: Parse the File into a Word Array

Your text uses the format 1. abacus (number + period + space + word), so first we need to strip out the extra characters and store just the words in an array.

After reading the file into your buffer, iterate through the content to:

  • Skip past the number, period, and space to reach the start of each word
  • Copy each word into a dedicated slot in an array (make sure each slot is big enough for your longest word plus a null terminator)
  • Track how many words you've parsed (we know it's 500, but dynamic counting makes the code more flexible)

Example Parsing Snippet

; Assumptions:
; - buffer contains the full file content
; - wordArray is a pre-allocated array of byte strings (each slot ~20 bytes for most English words)
; - wordCount tracks total parsed words

mov esi, offset buffer       ; Start at the beginning of the file content
mov edi, offset wordArray    ; Point to the start of our word storage array
mov ecx, 0                   ; Initialize word counter to 0

parse_loop:
    ; Skip characters until we hit the ". " separator
    cmp byte ptr [esi], '.'
    jne skip_char
    cmp byte ptr [esi+1], ' '
    jne skip_char
    add esi, 2               ; Move past ". " to the start of the word
    mov ebx, edi             ; Save the start of this word's slot

    ; Copy the word until we hit a newline or end of buffer
copy_word:
    mov al, [esi]
    cmp al, 0Ah              ; Check for newline (ASCII line feed)
    je end_of_word
    cmp al, 0                ; Check for end of buffer
    je end_parsing
    mov [edi], al
    inc edi
    inc esi
    jmp copy_word

end_of_word:
    mov byte ptr [edi], 0    ; Null-terminate the word
    inc edi                  ; Move to the next word slot (adjust based on your slot size)
    inc ecx                  ; Increment word count
    inc esi                  ; Move past the newline
    cmp ecx, 500             ; Stop once we've parsed all 500 words
    jl parse_loop

end_parsing:
    mov wordCount, ecx       ; Store the total number of words

Step 2: Add Random Number Generation

MASM doesn't have a built-in random function, but we can use Windows API's RtlRandom (from ntdll.dll) seeded with the system time to get unique random results each run.

Random Seed & Generator Setup

; sysTime is a SYSTEMTIME structure to hold current time
invoke GetSystemTime, offset sysTime

; Combine time values into a 32-bit seed
mov eax, [sysTime.wYear]
shl eax, 16
mov ax, [sysTime.wMonth]
shl eax, 8
mov al, [sysTime.wDay]
xor eax, [sysTime.wHour]
xor eax, [sysTime.wMinute]
xor eax, [sysTime.wSecond]
mov seed, eax

; Initialize the random generator (RtlRandom modifies the seed pointer)
invoke RtlRandom, offset seed

Step 3: Select 8 Unique Words

Generate random indices (0 to 499) and pick the corresponding words. We'll track used indices to avoid duplicates.

Selection & Display Snippet

; usedIndices is a 500-byte array initialized to 0 (0 = unused, 1 = used)
; selectedWords stores pointers to the 8 chosen words
mov ecx, 0                   ; Counter for selected words

select_loop:
    cmp ecx, 8
    je done_selecting

    ; Generate a random index between 0 and 499
    invoke RtlRandom, offset seed
    xor edx, edx
    mov ebx, 500
    div ebx                  ; edx holds the random index
    mov esi, edx

    ; Skip if this index was already used
    cmp byte ptr [usedIndices + esi], 1
    je select_loop

    ; Mark index as used and store the word pointer
    mov byte ptr [usedIndices + esi], 1
    mov eax, offset wordArray
    mov ebx, 20              ; Size of each word slot (adjust to match your array)
    mul esi
    add eax, offset wordArray
    mov [selectedWords + ecx*4], eax

    inc ecx
    jmp select_loop

done_selecting:
    ; Display the 8 selected words
    mov ecx, 0
display_loop:
    cmp ecx, 8
    je done_displaying
    invoke GetStdHandle, -11
    mov edx, [selectedWords + ecx*4]

    ; Calculate word length for WriteConsoleA
    mov ebx, edx
    mov eax, 0
count_length:
    cmp byte ptr [ebx], 0
    je end_count
    inc eax
    inc ebx
    jmp count_length
end_count:
    invoke WriteConsoleA, eax, edx, eax, offset x, 0
    ; Print a newline after each word
    mov edx, offset newline
    invoke WriteConsoleA, eax, edx, 1, offset x, 0
    inc ecx
    jmp display_loop

done_displaying:

Quick Tips

  • Buffer Size: Ensure your initial buffer is large enough to hold the entire 500-word file. If not, modify your ReadFile call to read in chunks.
  • Null Termination: Always null-terminate strings when using Windows API functions like WriteConsoleA—it prevents garbage output.
  • Slot Size: Adjust the word array slot size (20 in the example) to fit the longest word in your list.

内容的提问来源于stack exchange,提问作者Anmol Wajid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:17:07