String 程序集x86日期到编号-将字符串拆分为较小的部分
事实上,我希望在一个问题上被指向正确的方向 我希望将x86汇编中的日期从格式“DD-MMM-YYYY”转换为唯一的数字,以便稍后对其进行气泡排序并最终转换回 因此,当我有一个字符串输入时,即: .数据 inDate dw“1993年9月8日” 我想把它分成两部分String 程序集x86日期到编号-将字符串拆分为较小的部分,string,assembly,x86,masm32,String,Assembly,X86,Masm32,事实上,我希望在一个问题上被指向正确的方向 我希望将x86汇编中的日期从格式“DD-MMM-YYYY”转换为唯一的数字,以便稍后对其进行气泡排序并最终转换回 因此,当我有一个字符串输入时,即: .数据 inDate dw“1993年9月8日” 我想把它分成两部分 day = "08" month = "SEP" year = "1993" 这样我可以进一步处理它(我将把SEP转换为“7”,等等) 所以我的问题是,什么是一种简单有效的方式来分解日期(代码方面)?我知道我需要转换日期格式以允许排序
day = "08"
month = "SEP"
year = "1993"
这样我可以进一步处理它(我将把SEP转换为“7”,等等)
所以我的问题是,什么是一种简单有效的方式来分解日期(代码方面)?我知道我需要转换日期格式以允许排序,但我是汇编新手,所以我不确定如何分解字符串以便转换它
另外,作为第二个问题,如何将数字从字符串转换为实际的数值
谢谢
注:我想应该注意的是,我使用的是masm32,下一个小程序是用EMU8086(16位)编写的,它从键盘上捕获数字作为字符串,将它们转换为数字进行比较,最后将数字转换为字符串进行显示。请注意,数字是用0AH捕捉的,这需要一个3级变量“str”。您需要的转换过程位于代码的底部(string2number和number2string) 现在是32位版本。接下来是一个小程序,它为EAX分配一个大数字,将其转换为字符串并将其转换回数值,如下所示:
.model small
.586
.stack 100h
.data
msj1 db 13,10,'Original EAX = $'
msj2 db 13,10,'Flipped EAX = $'
msj3 db 13,10,'New EAX = $'
buf db 11
db ?
db 11 dup (?)
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;CONVERT EAX TO STRING TO DISPLAY IT.
call dollars ;NECESSARY TO DISPLAY.
mov eax, 1234567890
call number2string ;PARAMETER:AX. RETURN:VARIABLE BUF.
;DISPLAY 'ORIGINAL EAX'.
mov ah, 9
mov dx, offset msj1
int 21h
;DISPLAY BUF (EAX CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;FLIP EAX.
call dollars ;NECESSARY TO DISPLAY.
mov eax, 1234567890
call flip_eax ;PARAMETER:AX. RETURN:VARIABLE BUF.
;DISPLAY 'FLIPPED EAX'.
mov ah, 9
mov dx, offset msj2
int 21h
;DISPLAY BUF (EAX FLIPPED CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;CONVERT STRING TO NUMBER (FLIPPED EAX TO EAX).
mov si, offset buf ;STRING TO REVERSE.
call string2number ;RETURN IN EBX.
mov eax, ebx ;THIS IS THE NEW EAX FLIPPED.
;CONVERT EAX TO STRING TO DISPLAY IT.
call dollars ;NECESSARY TO DISPLAY.
call number2string ;PARAMETER:EAX. RETURN:VARIABLE BUF.
;DISPLAY 'NEW EAX'.
mov ah, 9
mov dx, offset msj3
int 21h
;DISPLAY BUF (EAX CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;WAIT UNTIL USER PRESS ANY KEY.
mov ah, 7
int 21h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;------------------------------------------
flip_eax proc
mov si, offset buf ;DIGITS WILL BE STORED IN BUF.
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
extracting:
;EXTRACT ONE DIGIT.
mov edx, 0 ;NECESSARY TO DIVIDE BY EBX.
div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
;INSERT DIGIT IN STRING.
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
;NEXT DIGIT.
cmp eax, 0 ;IF NUMBER IS
jne extracting ;NOT ZERO, REPEAT.
ret
flip_eax endp
;------------------------------------------
;CONVERT STRING TO NUMBER IN EBX.
;SI MUST ENTER POINTING TO THE STRING.
string2number proc
;COUNT DIGITS IN STRING.
mov cx, 0
find_dollar:
inc cx ;DIGIT COUNTER.
inc si ;NEXT CHARACTER.
mov bl, [ si ]
cmp bl, '$'
jne find_dollar ;IF BL != '$' JUMP.
dec si ;BECAUSE IT WAS OVER '$', NOT OVER THE LAST DIGIT.
;CONVERT STRING.
mov ebx, 0
mov ebp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov eax, 0 ;NOW EAX==AL.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mul ebp ;EAX*EBP = EDX:EAX.
add ebx, eax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov eax, ebp
mov ebp, 10
mul ebp ;AX*10 = EDX:EAX.
mov ebp, eax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;CX-1, IF NOT ZERO, REPEAT.
ret
string2number endp
;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
dollars proc
mov si, offset buf
mov cx, 11
six_dollars:
mov bl, '$'
mov [ si ], bl
inc si
loop six_dollars
ret
dollars endp
;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN EAX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).
number2string proc
mov ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov edx, 0 ;NECESSARY TO DIVIDE BY EBX.
div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp eax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
mov si, offset buf
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
end start
我了解很多,但我在DD-MMM-YYYY接受我的治疗。因此,我想将DD-MMM-YYYY分解为单独的片段进行转换,以便以这种方式进行排序。要对日期进行排序,需要YYYYMMDD,因为这种格式允许您进行比较。例如,你可以用它来比较出生日期,找出谁更年轻或更老:20150514比20150502晚。对,我明白了。但日期将以DD-MMM-YYYY的形式出现,不幸的是,无法回避这一点。所以,我要做的是将其转换为YYYYMMDD、气泡排序和输出。因此,我的问题是让我在DateToNumber过程中指出正确的方向,该过程将采用DD-MM-YYYY格式parm并返回YYYYMMDD号。如果日期采用DD-MM-YYYY格式,请执行以下操作:从右到左访问所有字符,将每个字符移动到另一个字符串,忽略连字符,您将得到YYYYMMDD号,然后使用我的过程string2number对其进行转换。也许我应该这样做,让我的答案被接受^ uº:你用什么编译器进行汇编?Visual Studio?谢谢,我应该能够调整转换过程以获得所需的内容。这是有道理的。
printf
对于只将字符串传递到ah=9/int 21h
而不查找%d
转换或任何内容的函数来说不是一个很好的名称。也许DOS\u put
会是一个更好的名称(尽管Cput
附加了一个换行符,这需要一个终止的$
而不是'\0'')。也许只要
print_string`就更好了。它绝对不是printf
,因为f
代表“格式化”。从最有效的数字开始计算并累加total*=10更有效;总计+=下一位数字
。在asm中,总计可以始终保持在AX
,并且每个循环迭代只需要一个mul
。
.model small
.586
.stack 100h
.data
msj1 db 13,10,'Original EAX = $'
msj2 db 13,10,'Flipped EAX = $'
msj3 db 13,10,'New EAX = $'
buf db 11
db ?
db 11 dup (?)
.code
start:
;INITIALIZE DATA SEGMENT.
mov ax, @data
mov ds, ax
;CONVERT EAX TO STRING TO DISPLAY IT.
call dollars ;NECESSARY TO DISPLAY.
mov eax, 1234567890
call number2string ;PARAMETER:AX. RETURN:VARIABLE BUF.
;DISPLAY 'ORIGINAL EAX'.
mov ah, 9
mov dx, offset msj1
int 21h
;DISPLAY BUF (EAX CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;FLIP EAX.
call dollars ;NECESSARY TO DISPLAY.
mov eax, 1234567890
call flip_eax ;PARAMETER:AX. RETURN:VARIABLE BUF.
;DISPLAY 'FLIPPED EAX'.
mov ah, 9
mov dx, offset msj2
int 21h
;DISPLAY BUF (EAX FLIPPED CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;CONVERT STRING TO NUMBER (FLIPPED EAX TO EAX).
mov si, offset buf ;STRING TO REVERSE.
call string2number ;RETURN IN EBX.
mov eax, ebx ;THIS IS THE NEW EAX FLIPPED.
;CONVERT EAX TO STRING TO DISPLAY IT.
call dollars ;NECESSARY TO DISPLAY.
call number2string ;PARAMETER:EAX. RETURN:VARIABLE BUF.
;DISPLAY 'NEW EAX'.
mov ah, 9
mov dx, offset msj3
int 21h
;DISPLAY BUF (EAX CONVERTED TO STRING).
mov ah, 9
mov dx, offset buf
int 21h
;WAIT UNTIL USER PRESS ANY KEY.
mov ah, 7
int 21h
;FINISH PROGRAM.
mov ax, 4c00h
int 21h
;------------------------------------------
flip_eax proc
mov si, offset buf ;DIGITS WILL BE STORED IN BUF.
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
extracting:
;EXTRACT ONE DIGIT.
mov edx, 0 ;NECESSARY TO DIVIDE BY EBX.
div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
;INSERT DIGIT IN STRING.
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
;NEXT DIGIT.
cmp eax, 0 ;IF NUMBER IS
jne extracting ;NOT ZERO, REPEAT.
ret
flip_eax endp
;------------------------------------------
;CONVERT STRING TO NUMBER IN EBX.
;SI MUST ENTER POINTING TO THE STRING.
string2number proc
;COUNT DIGITS IN STRING.
mov cx, 0
find_dollar:
inc cx ;DIGIT COUNTER.
inc si ;NEXT CHARACTER.
mov bl, [ si ]
cmp bl, '$'
jne find_dollar ;IF BL != '$' JUMP.
dec si ;BECAUSE IT WAS OVER '$', NOT OVER THE LAST DIGIT.
;CONVERT STRING.
mov ebx, 0
mov ebp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov eax, 0 ;NOW EAX==AL.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mul ebp ;EAX*EBP = EDX:EAX.
add ebx, eax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov eax, ebp
mov ebp, 10
mul ebp ;AX*10 = EDX:EAX.
mov ebp, eax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;CX-1, IF NOT ZERO, REPEAT.
ret
string2number endp
;------------------------------------------
;FILLS VARIABLE STR WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THE STRING WILL BE DISPLAYED.
dollars proc
mov si, offset buf
mov cx, 11
six_dollars:
mov bl, '$'
mov [ si ], bl
inc si
loop six_dollars
ret
dollars endp
;------------------------------------------
;NUMBER TO CONVERT MUST ENTER IN EAX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).
number2string proc
mov ebx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov edx, 0 ;NECESSARY TO DIVIDE BY EBX.
div ebx ;EDX:EAX / 10 = EAX:QUOTIENT EDX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED (DL) FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp eax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
mov si, offset buf
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
number2string endp
end start