【发布时间】:2015-02-13 19:47:01
【问题描述】:
无法使用字符串数组并从中获取每个字符并将 1 添加到相应 ascii 索引的频率表中(频率表由 ascii 值索引):例如,获取字符“a”然后将 1 添加到数组 ['a'] 的索引频率表。我收到分段错误,现在收到错误:操作码和操作数的无效组合,谈论mov ax, al
有关问题的参数的任何问题,请询问。我已经为此工作了几个小时,并且真的可以用另一双眼睛来检查我做错了什么(语法/概念如果你看到一个)请帮忙。
更新:我已经把它打印出来了,所以我认为它正在“工作”;但是我现在正在尝试打印每个数组索引对应的字符。它不会打印我指向的数组的字符(它实际上不打印字符)。
最新更新:我让它工作了。更改了标签 .loopa 下的一些代码,现在它可以正常工作了! :) 代码如下:
SECTION .data ; Data section, initialized variables
array5: db "Hello, world...", 0
array5Len: equ $-array5-1
asoutput: db "%s", 0 ; string output
newline: db "", 10, 0 ; format for a new line
acoutput: db "%c: ", 0 ; output format for character output
SECTION .bss ; BSS, uninitialized variables
arrayq: resd 128 ; frequency array of the first 127 ascii values initialized to 0 (none have been counted yet)
SECTION .text
global main ; the standard gcc entry point
main: ; the program label for the entry point
push ebp ; set up stack frame
mov ebp,esp
mov esi, array5
mov edi, 0
mov ebx, arrayq
mov ecx, array5Len
; get each character of array5 and add 1 to the frequency table of the corresponding ascii value (which the arrayq is indexed by ascii value).
.loopf:
xor eax, eax
mov al, [esi]
;mov ax, [esi]
;mov ax, al
;mov cx, ax
add edi, eax
mov ebx, 1
add [arrayq+4*edi], ebx
mov edi, 0
add esi, 1
loop .loopf
push dword array2
push dword asoutput
call printf
add esp, 8
push dword newline
call printf
add esp, 4
;pop ebx
mov ebx, arrayq
mov ecx, 128 ; size of arrayq
mov esi, 0 ;start at beginning
.loopa:
mov eax, 0
cmp [ebx+esi], eax
je .skip
mov eax, esi
push ebx
push ecx
mov ebx, 4
cdq
div ebx
push eax
push dword acoutput
call printf
add esp, 8
pop ecx
pop ebx
push ebx
push ecx ; make sure to put ecx (counter) on stack so we don't lose it when calling printf)
push dword [ebx + esi] ; put the value of the array at this (esi) index on the stack to be used by printf
push dword aoutput ; put the array output format on the stack for printf to use
call printf ; call the printf command
add esp, 8 ; add 4 bytes * 2
pop ecx ; get ecx back
pop ebx
push ebx
push ecx
push dword newline
call printf
add esp, 4
pop ecx
pop ebx
.skip:
add esi, 4
loop .loopa
.end:
mov esp, ebp ; takedown stack frame
pop ebp ; same as "leave" op
【问题讨论】:
-
mov ax, al不起作用,因为您要求将 8 位值移动到 16 位寄存器。然而,无论如何,这一举动毫无意义,因为al、ax和eax都是同一个寄存器,分别只是低 8 位、低 16 位和完整的 32 位。因此,在您的mov al, [esi]之后,您可以立即使用eax值来索引您的频率表。 -
@500-InternalServerError 感谢解决了程序的那一部分,现在我有一个“稍微”不同的问题......
-
也许我不明白你的代码,但它不是获取 char 并将其用作 ascii-count-array arrayq 的索引的最简单方法,如下所示:
add [arrayq + 4*eax], dword 1?嗯,您需要先用零初始化您的 ascii 计数 arraayq,还是?一个循环:mov ecx, 128,mov [arrayq + 4 * ecx], dword 0 -
@Blechdose 程序必须有一个 ascii 值的频率数组,所有值都初始化为零才能启动:/
-
@Rex 由于 arrayq 位于 .BSS 部分,因此您需要将其内容显式归零。到目前为止,您的代码还没有这样做。
标签: arrays assembly printf character nasm